Подтвердить что ты не робот

Ключевое слово Prototype в Javascript

Что такое свойство prototype и почему оно необходимо? До сих пор я узнал, что это обеспечивает открытый доступ к более внутреннему и частному prototype объекта; это верно?

Кроме того, в чем разница между следующими утверждениями?

MyConstructor.age = 30;
MyConstructor.prototype.age = 30;

Короче говоря, мне нужно лучше понять prototype ключевого слова.

Спасибо

4b9b3361

Ответ 1

"Prototype" - это то, что играет роль в объектах.

В Javascript все является объектом. Каждый объект имеет вид и, таким образом, наследует prototype такого типа.

Например, возьмите простой массив: var a = []. Вы можете выполнять операции с ним, например a.push(10). Откуда этот метод push? Из прототипа объекта Array, который a есть.

Вы можете добавить свои собственные методы к объектам Array, просто указав их в объекте prototype. Например:

Array.prototype.sortNum = function() {this.sort(function(a, b) {return a - b});};

Таким образом вы можете сделать что-то вроде a.sortNum() со всеми массивами, даже теми, которые были созданы до того, как вы определили метод sortNum.

(Примечание: по соображениям совместимости обычно не рекомендуется расширять прототип собственных объектов, таких как Array s. Но этот конкретный пример обычно является приятным дополнением, а также нормализацией таких методов, как map и forEach для старых браузеров.)

(Только никогда никогда не расширяется Object.prototype! Если вы не хотите испортить операторы for...in, оператор in и подобные случаи.)

Если вы хотите определить свои собственные классы, как предлагает название MyConstructor, вам нужно будет определить его prototype, чтобы определить методы для всех экземпляров этого класса:

function MyConstructor(name) {this.name = name};
MyConstructor.prototype = {
    print: function() {return this.name;}
};

var mc = new MyConstructor("foo");
alert(mc.print()); // alerts "foo"

Вы можете определить больше, чем просто функции в prototype s:

MyConstructor.prototype.age = 30;

alert(mc.age); // alerts 30

Остерегайтесь, когда вы делаете это, чтобы определить значения объекта по умолчанию, поскольку изменение его может привести к изменению во всех экземплярах этого класса.

Но это удобно при использовании Object.defineProperty:

Object.defineProperty(MyConstructor.prototype, "wholeString", {
    get: function() {return this.name + "=" + this.age;},
    set: function(v) {this.name = v.substring(3);}
});

alert(mc.wholeString); // alerts "foo = 30"

(К сожалению, IE < 9 допускает это только для объектов DOM...)

Когда вы определяете MyConstructor.age = 30 вместо этого, то, что вы на самом деле делаете, определяет член функции MyConstructor, поэтому mc.age будет undefined. Каждый экземпляр MyConstructor наследует методы и члены, определенные в MyConstructor.prototype, а не те функции MyConstructor.

На самом деле гораздо больше можно сказать. Объекты могут быть подкласса другого класса, таким образом, наследуя prototype суперкласса. Например, document.body является экземпляром HTMLBodyElement, который является подклассом HTMLElement, который является подклассом Element и т.д., Пока вы не получите Object в качестве верхнего суперкласса. Таким образом, document.body наследует все методы, определенные в прототипе HTMLBodyElement, HTMLElement, Element и Object. Это называется цепочкой прототипов.

Выполнение этого же с пользовательскими объектами немного сложно:

function Class() {};
Class.prototype.foo = function() {alert("foo");};

function Subclass() {};
Subclass.prototype = new Class();
Subclass.prototype.bar = function() {alert("bar");};

var a = new Class(), b = new Subclass();
a.foo(); // alerts"foo"
a.bar(); // throws an error
b.foo(); // alerts "foo"
b.bar(); // alerts "bar"

a instanceof Class;    // true
a instanceof Subclass; // false
b instanceof Class;    // true
b instanceof Subclass; // true

Ответ 2

В JavaScript объекты функций имеют встроенное свойство .prototype. Значение этого свойства является объектом. Если функция используется как конструктор, результирующие экземпляры наследуют от этого объекта "prototype".

Пример:

var Dog = function () {}; // the constructor function

Dog.prototype.bark = function () {}; // adding a method to Dog.prototype

var dog1 = new Dog; // creating a new instance

dog1.bark(); // the instance inherits the "bark" method from Dog.prototype

Обратите внимание, что свойство .prototype (объектов функции) не совпадает с внутренним свойством [[Prototype]]. Все объекты содержат последние. Это внутренняя ссылка на прототип объекта. (В приведенном выше примере объект dog1 [[Prototype]] относится к Dog.prototype.) С другой стороны, только объекты-объекты имеют встроенное свойство .prototype (что имеет смысл, поскольку только объекты-объекты могут использоваться как конструкторы).

Ответ 3

var foo = function () {};
foo.bar = 5;
foo.prototype.foobar = 10;

var x = new foo();
x.bar; // undefined
x.foobar; // 10

Изменить: Кроме того, вы можете сделать

foo.prototype.foobar = 20;
x.foobar; // 20