SPOSOBY ROZSZERZENIA obiektu Array w javascript
Staram się rozszerzyć obiekt Array w javascript za pomocą kilku przyjaznych dla użytkownika metod, takich jak Array.Add () zamiast tablicy.push() itd...
Wdrażam 3 sposoby, aby to zrobić. niestety trzecia droga nie działa i chcę zapytać dlaczego? i jak to zrobić działa.
//------------- 1st way
Array.prototype.Add=function(element){
this.push(element);
};
var list1 = new Array();
list1.Add("Hello world");
alert(list1[0]);
//------------- 2nd way
function Array2 () {
//some other properties and methods
};
Array2.prototype = new Array;
Array2.prototype.Add = function(element){
this.push(element);
};
var list2 = new Array2;
list2.Add(123);
alert(list2[0]);
//------------- 3rd way
function Array3 () {
this.prototype = new Array;
this.Add = function(element){
this.push(element);
};
};
var list3 = new Array3;
list3.Add(456); //push is not a function
alert(list3[0]); // undefined
W trzeci sposób chcę rozszerzyć obiekt Array wewnętrznie klasy Array3. Jak to zrobić, aby nie dostać "push is not a function" I "undefined"?
Tutaj dodaję czwarty sposób.
//------------- 4th way
function Array4 () {
//some other properties and methods
this.Add = function(element){
this.push(element);
};
};
Array4.prototype = new Array();
var list4 = new Array4();
list4.Add(789);
alert(list4[0]);
Tutaj znowu muszę użyć prototyp. Miałem nadzieję uniknąć używania dodatkowych linii poza konstruktorem klasy jako Array4.prototyp. Chciałem mieć kompaktową, zdefiniowaną klasę ze wszystkimi elementami w jednym miejscu. Ale myślę, że nie mogę tego zrobić inaczej.
8 answers
Nazwy metod powinny być pisane małymi literami. Prototyp nie powinien być modyfikowany w konstruktorze.
function Array3() { };
Array3.prototype = new Array;
Array3.prototype.add = Array3.prototype.push
W CoffeeScript
class Array3 extends Array
add: (item)->
@push(item)
Jeśli nie podoba Ci się ta składnia i musisz ją rozszerzyć z konstruktora, Twoja jedyna opcja to:
// define this once somewhere
// you can also change this to accept multiple arguments
function extend(x, y){
for(var key in y) {
if (y.hasOwnProperty(key)) {
x[key] = y[key];
}
}
return x;
}
function Array3() {
extend(this, Array.prototype);
extend(this, {
Add: function(item) {
return this.push(item)
}
});
};
Możesz też to zrobić
ArrayExtenstions = {
Add: function() {
}
}
extend(ArrayExtenstions, Array.prototype);
function Array3() { }
Array3.prototype = ArrayExtenstions;
W dawnych czasach " prototyp.js miał zajęcia.Utwórz metodę. Można to wszystko zawinąć jest to metoda taka
var Array3 = Class.create(Array, {
construct: function() {
},
Add: function() {
}
});
Aby uzyskać więcej informacji na ten temat i jak wdrożyć, zajrzyj do prototyp.kod źródłowy js
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-06 15:48:32
ES6
class SubArray extends Array {
constructor(...args) {
super(...args);
}
last() {
return this[this.length - 1];
}
}
var sub = new SubArray(1, 2, 3);
sub // [1, 2, 3]
sub instanceof SubArray; // true
sub instanceof Array; // true
Za pomocą __proto__
(stara odpowiedź, niezalecana, może powodować problemy z wydajnością)
function SubArray() {
var arr = [ ];
arr.push.apply(arr, arguments);
arr.__proto__ = SubArray.prototype;
return arr;
}
SubArray.prototype = new Array;
Teraz możesz dodać swoje metody do SubArray
SubArray.prototype.last = function() {
return this[this.length - 1];
};
Inicjalizacja jak normalne Tablice
var sub = new SubArray(1, 2, 3);
Zachowuje się jak normalne Tablice
sub instanceof SubArray; // true
sub instanceof Array; // true
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-24 03:16:42
W trzecim przykładzie tworzysz nową właściwość o nazwie prototype
dla obiektu Array3
. Kiedy wykonujesz new Array3
, które powinno być new Array3()
, tworzysz instancję tego obiektu do zmiennej list3
. Dlatego metoda Add
nie będzie działać, ponieważ this
, który jest danym obiektem, nie ma poprawnej metody push
. Mam nadzieję, że rozumiesz.
Edit: Sprawdź zrozumienie kontekstu JavaScript aby dowiedzieć się więcej o this
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-21 14:15:40
Jakiś czas temu przeczytałem książkę Javascript Ninja napisaną przez Johna Resiga , twórcę jQuery .
Zaproponował sposób naśladowania metod typu array za pomocą zwykłego obiektu JS. Zasadniczo wymagane jest tylko length
.
var obj = {
length: 0, //only length is required to mimic an Array
add: function(elem){
Array.prototype.push.call(this, elem);
},
filter: function(callback) {
return Array.prototype.filter.call(this, callback); //or provide your own implemetation
}
};
obj.add('a');
obj.add('b');
console.log(obj.length); //2
console.log(obj[0], obj[1]); //'a', 'b'
Nie chodzi mi o to, że to dobre czy złe. To oryginalny sposób wykonywania Array
operacji. Korzyść polega na tym, że nie przedłużasz Array prototype
.
Należy pamiętać, że obj
jest zwykłym object
, nie jest Array
. Dlatego obj instanceof Array
zwróci false
. Think obj
jako fasada .
Jeśli ten kod Cię interesuje, przeczytaj fragment Listing 4.10 Simulating array-like methods .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-03 13:35:51
Czy próbujesz zrobić coś bardziej skomplikowanego, a następnie dodać alias dla " push "o nazwie "Add"?
Jeśli nie, prawdopodobnie najlepiej byłoby tego uniknąć. Powodem, dla którego sugeruję, że jest to zły pomysł, jest to, że ponieważ tablica jest wbudowanym typem javascript, jego modyfikacja spowoduje, że wszystkie typy tablicy skryptów będą miały nową metodę "Add". Potencjał kolizji nazw z inną stroną trzecią jest wysoki i może spowodować, że skrypt strony trzeciej straci swoją metodę na rzecz Twojej.
My ogólną zasadą jest, aby funkcja pomocnicza działała na tablicy, jeśli już gdzieś nie istnieje i rozszerza tablicę tylko wtedy, gdy jest bardzo potrzebna.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-05 04:53:16
Nie można rozszerzyć obiektu Array w JavaScript.
Zamiast tego, możesz zdefiniować obiekt, który będzie zawierał listę funkcji, które wykonują się w tablicy, i wstrzyknąć te funkcje do tej instancji tablicy i zwrócić tę nową instancję tablicy. Nie powinieneś zmieniać Array.prototype
, aby włączyć swoje niestandardowe funkcje na liście.
Przykład:
function MyArray() {
var tmp_array = Object.create(Array.prototype);
tmp_array = (Array.apply(tmp_array, arguments) || tmp_array);
//Now extend tmp_array
for( var meth in MyArray.prototype )
if(MyArray.prototype.hasOwnProperty(meth))
tmp_array[meth] = MyArray.prototype[meth];
return (tmp_array);
}
//Now define the prototype chain.
MyArray.prototype = {
customFunction: function() { return "blah blah"; },
customMetaData: "Blah Blah",
}
Tylko przykładowy kod, możesz go modyfikować i używać jak chcesz. Ale podstawowa koncepcja I polecam do naśladowania pozostaje taka sama.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-07 20:42:20
Możesz również użyć tego sposobu w ES6:
Object.assign(Array.prototype, {
unique() {
return this.filter((value, index, array) => {
return array.indexOf(value) === index;
});
}
});
Wynik:
let x = [0,1,2,3,2,3];
let y = x.unique();
console.log(y); // => [0,1,2,3]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-08 15:41:14
var SubArray = function() {
var arrInst = new Array(...arguments); // spread arguments object
/* Object.getPrototypeOf(arrInst) === Array.prototype */
Object.setPrototypeOf(arrInst, SubArray.prototype); //redirectionA
return arrInst; // now instanceof SubArray
};
SubArray.prototype = {
// SubArray.prototype.constructor = SubArray;
constructor: SubArray,
// methods avilable for all instances of SubArray
add: function(element){return this.push(element);},
...
};
Object.setPrototypeOf(SubArray.prototype, Array.prototype); //redirectionB
var subArr = new SubArray(1, 2);
subArr.add(3); subArr[2]; // 3
Odpowiedzią jest kompaktowe obejście, które działa zgodnie z przeznaczeniem we wszystkich obsługiwanych przeglądarkach.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-31 18:49:31