2015-09-03 2 views
0

Я новичок в изучении концепции наследования в JavaScript. В этом контексте я хотел бы наследовать объект Array и добавлять к нему функциональные возможности.
Проблема заключается в том, что метод third выполняется правильно, но метод show() вызывает ошибку, заявляя, что show() не является функцией.О наследовании свойств объекта массива в javascript

var a = [1,2,3,4,5]; 
Array.prototype = { 
    third:function(){ 
     console.log(a[3]); 
    }, 
    show:function(){ 
     console.log(a); 
    } 
}; 
a.third(); 
a.show(); 
+0

Где код для справки? –

+0

Пожалуйста, отправьте образец кода. – bfontaine

+1

Это действительно плохо, потому что то, что вы делаете, заменяет _all_ methods на прототипе Array своим. Пожалуйста, не делайте этого. – Andy

ответ

0

Вместо этого, попробуйте так:

var array = [1,2,3,4,5]; 
Array.prototype.third = function() { console.log(this[3]); } 
Array.prototype.show = function() { console.log(this); } 
array.third(); 
array.show(); 
0

Если вы собираетесь добавлять методы в родных прототипов, вам действительно нужно поставить галочку в месте, так что вы можете быть уверены, вы не отменяете ничего важного. Таким образом, чтобы взять ваш пример и изменить его немного:

if (!('third' in Array.prototype)) { 
    Array.prototype.third = function() { 
    return this[2]; 
    }; 
} 

[0, 1, 2, 3].third(); // 2 

DEMO

2

Проблема заключается в том, что ваш код пытается заменить встроенный в прототип (который сам по себе является массивом) с равниной объект, который имеет только свойства, которые вы назначаете. Вместо замены прототипа добавьте свойства к тому, который уже существует, например.

Array.prototype.third = function() { 
    console.log(a[3]); 
} 

Кроме того, поскольку вы создаете в массив перед заменой Array.prototype, это получить самый старый прототип, не новый (если новый добавляется совсем). Оба метода бросают ошибки, а не только показывают. Если вы измените прототип до, создав a, он «работает» в браузерах, которые позволяют перезаписывать встроенные прототипы. Он не будет работать в ECAMScript эд 3 (или, возможно, раньше) реализации или позже, где Array.prototype имеет атрибуты:

{ [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false } 

так что вы не можете заменить его, а сам объект имеет атрибуты:

{ [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false } 

, так что вы можете добавить свойства и перезаписать встроенные методы, если хотите.

Обратите внимание на то, что, как правило, предупреждают о распространении встроенных объектов, см. Extending builtin natives. Evil or not?.

+0

Кроме того, массивы, построенные из литералов массива, не наследуются от 'Array.prototype', они наследуют от внутреннего% ArrayPrototype%, который в любом случае не может быть перезаписан назначениями Array.prototype (по крайней мере с ES5). – Bergi

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