2016-09-07 5 views
0

Я просто играю с идеей подкласса с Javascript. Мне нравится притворяться, что расширение собственных объектов (например, Array, String и т. Д.) - плохая идея. Это, правда, совершенно не в моем понимании, почему.Невозможно расширить прототип javascript

Сказав это, давайте продолжим.

То, что я пытаюсь сделать, это расширить массив (теперь, extend не может быть правильный термин для того, что я делаю)

Я хочу создать новый класс и я хочу иметь 2 методов в теме. .add и .addMultiple.

Итак, я реализовал это так.

function MyArray(){ 
    var arr = Object.create(Array.prototype); 
    return Array.apply(arr, arguments); 
} 

MyArray.prototype = Array.prototype; 

MyArray.prototype.add = function(i){ 
    this.push(i); 
} 

MyArray.prototype.addMultiple = function(a){ 
    if(Array.isArray(a)){ 
     for(var i=0;i<a.length;i++){ 
      this.add(a[i]); 
     } 
    } 
} 

Это работает правильно, но если я

console.log(Array.prototype.addMultiple); 
console.log(Array.prototype.add); 

я [Function] и [Function]. Так что это означает, что мой код изменяет собственный объект Array. Что-то, чего я пытаюсь избежать. Как мне изменить этот код так, чтобы эти два console.log s дали мне undefined, но я все еще могу использовать собственные методы Array.prototype, например .push?

ТИА

ответ

1

Вы должны установить правильный прототипов цепи:

function MyArray(){ 
    Array.apply(this, arguments); 
} 

MyArray.prototype = Object.create(Array.prototype); 

Object.create просто создает новый объект с указанным прототипом, так что после этой операции верно следующее:

MyArray.prototype !== Array.prototype; // true 
Object.getPrototypeOf(MyArray.prototype) === Array.prototype; // true 
+0

Было бы также правильным сказать, что текущее содержимое 'MyArray' (конструктор) действительно не нужно? – Katana314

+0

Нет, это не позволит мне делать «MyArray.prototype.add». '.add' не будет определен. – AdityaParab

+0

@ Katana314: Нет! «Var arr = Object.create (Array.prototype);' в конструкторе - это просто явный способ сказать «var arr = []'; – AdityaParab

0

Это:

MyArray.prototype = Array.prototype;

результат MyArray.prototype, указывающий на тот же объект, что и Array.prototype. Итак, все, что вы делаете с MyArray.prototype после этого, также будет сделано для Array.prototype.

способ решить это, чтобы вместо того, чтобы хранить неполную копию прототипа массива в MyArray:

MyArray.prototype = клон (Array.prototype);

Я скопировал отсюда:

Copy prototype for inheritance?

+0

Спасибо, я посмотрю – AdityaParab

0

использования класса extension

class MyArray extends Array { 
 
    add(i) { 
 
    this.push(i); 
 
    return this; 
 
    } 
 
    addMultiple(a) { 
 
    if (Array.isArray(a)) { 
 
     for (var i = 0; i < a.length; i++) { 
 
     this.add(a[i]); 
 
     } 
 
    } 
 
    return this; 
 
    } 
 
} 
 

 
var test = new MyArray(); 
 
test.addMultiple([1,2,3,4,5]).add(6).add(7); 
 
console.log(test, test.indexOf(6));

+1

Спасибо, я хочу сделать это с помощью ES5! – AdityaParab

0
Object.create(Array.prototype); 

Это просто создает новый объект и вернуть объективистские ц.

В соответствии с вашими сценариями вы только что создали объект массива и добавили некоторые методы к вашему объекту массива - MyArray. Это повлияет на собственный массив.

Вы просто модифицируете свой клонированный объект.

Смежные вопросы