objetos matriz into elementos array agregar javascript arrays class extend

matriz - Formas de extender el objeto Array en javascript



push array into array javascript (8)

Intento extender el objeto Array en javascript con algunos métodos fáciles de usar como Array.Add () en lugar de Array.push () etc ...

Implemento 3 formas de hacer esto. desafortunadamente, la tercera forma no funciona y quiero preguntar por qué? y cómo hacerlo funcionar

//------------- 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

en 3ra forma quiero extender el objeto Array internamente a la clase Array3. ¿Cómo hacer esto para no obtener "push" no es una función "y" undefined "?

Aquí agrego una 4ª manera.

//------------- 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]);

Aquí otra vez tengo que usar un prototipo. Esperaba evitar el uso de líneas adicionales fuera del constructor de clase como Array4.prototype. Quería tener una clase compacta definida con todas las piezas en un solo lugar. Pero creo que no puedo hacerlo de otra manera.


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

Usando __proto__

(La respuesta anterior, no recomendada, puede causar problemas de rendimiento )

function SubArray() { var arr = [ ]; arr.push.apply(arr, arguments); arr.__proto__ = SubArray.prototype; return arr; } SubArray.prototype = new Array;

Ahora puede agregar sus métodos a SubArray

SubArray.prototype.last = function() { return this[this.length - 1]; };

Inicializar como matrices normales

var sub = new SubArray(1, 2, 3);

Se comporta como matrices normales

sub instanceof SubArray; // true sub instanceof Array; // true


¿Estás tratando de hacer algo más complicado que solo agregar un alias para "presionar" llamado "Agregar"?

Si no, probablemente sería mejor evitar hacer esto. La razón por la que sugiero que esto es una mala idea es que, dado que Array es un tipo de JavaScript incorporado, al modificarlo, todas las secuencias de comandos Tipo de matriz tendrán su nuevo método "Agregar". El potencial de conflictos de nombres con otro tercero es alto y podría hacer que el script de terceros pierda su método a favor de uno.

Mi regla general es hacer que una función auxiliar funcione en la matriz si ya no existe en alguna parte y solo extender la matriz si es extremadamente necesario.


En su tercer ejemplo, solo está creando una nueva propiedad llamada prototype para el objeto Array3 . Cuando new Array3 que debería ser new Array3() , estás instanciando ese objeto en la lista de variables3. Por lo tanto, el método Add no funcionará porque this , que es el objeto en cuestión, no tiene un método push válido. Espero que entiendas.

Editar: consulte Entender el contexto de JavaScript para obtener más información al this .


Hace un tiempo leí el libro Javascript Ninja escrito por John Resig , el creador de jQuery . Propuso una forma de imitar los métodos tipo array con un objeto JS simple. Básicamente, solo se requiere 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''

No me refiero a que sea bueno o malo. Es una forma original de hacer operaciones Array . El beneficio es que no extiende el Array prototype . Tenga en cuenta que obj es un object simple, no es una Array . Por lo tanto, obj instanceof Array devolverá false . Piensa en obj como una fachada .

Si ese código es de su interés, lea el extracto Listado 4.10. Simulación de métodos tipo array .


Los nombres de los métodos deben ser minúsculos. El prototipo no se debe modificar en el constructor.

function Array3() { }; Array3.prototype = new Array; Array3.prototype.add = Array3.prototype.push

en CoffeeScript

class Array3 extends Array add: (item)-> @push(item)

Si no le gusta esa sintaxis, y TIENE que extenderla desde el constructor, su única opción es:

// 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) } }); };

También podrías hacer esto

ArrayExtenstions = { Add: function() { } } extend(ArrayExtenstions, Array.prototype); function Array3() { } Array3.prototype = ArrayExtenstions;

En el pasado, ''prototype.js'' solía tener un método Class.create. Podrías envolver todo esto es un método como ese

var Array3 = Class.create(Array, { construct: function() { }, Add: function() { } });

Para obtener más información sobre esto y cómo implementarlo, busque en el código fuente de prototype.js


NO PUEDE extender el objeto Array en JavaScript.

En cambio, lo que puede hacer es definir un objeto que contendrá una lista de funciones que se realizan en la matriz, e inyectar estas funciones en esa instancia de matriz y devolver esta nueva instancia de matriz. Lo que no debe hacer es cambiar Array.prototype para incluir sus funciones personalizadas en la lista.

Ejemplo:

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", }

Solo un código de muestra, puede modificarlo y usarlo como lo desee. Pero el concepto subyacente que recomiendo seguir es el mismo.


También puedes usarlo de esta manera en ES6:

Object.assign(Array.prototype, { unique() { return this.filter((value, index, array) => { return array.indexOf(value) === index; }); } });

Resultado:

let x = [0,1,2,3,2,3]; let y = x.unique(); console.log(y); // => [0,1,2,3]


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

La respuesta es una solución compacta que funciona según lo previsto en todos los navegadores compatibles.