(простое объяснение)
Свойство prototype
применяется только при использовании function
в качестве конструктора (с помощью оператора new
). function
создает клон его prototype
, а ключевое слово this
внутри функции устанавливается на клон. Свойства клона являются прямыми ссылками / указателями на свойства prototypes
.
Литерал объекта {}
является более мощным выражением, альтернативным new Object()
, и поэтому «наследует» свойства от Object.prototype
.
Итак:
function ClassLike() {}
ClassLike.prototype = {
foo : "bar"
}
var instance = new ClassLike();
alert( instance.foo ); // bar
Работает, потому что оператор new
запускает некоторые операции в движении, чтобы создать новый объект, тогда как:
var instance = {
foo : "bar"
}
instance.prototype = {
baz : "foobar"
}
Просто добавляет другое свойство (прототип) к уже созданному объекту, и никакой процесс не запускается для фактического назначения / изменения исходного прототипа объектов.
Теперь Mozilla добавила нестандартный (IE не поддерживает его) способ изменить прототип уже созданного объекта с помощью __proto__
, и есть некоторые петиции, которые собираются добавить его в ES5 (EcmaScript 5). Я бы не стал его использовать. но это работает так:
var instance = {};
var parent = {
foo : "bar"
}
instance.__proto__ = parent;
alert( instance.foo ); // bar
Еще один способ изменить прототип уже созданного объекта - добавить к прототипу конструкторов Object
(что по многим причинам не рекомендуется). Как таковой:
var instance = {}; // a more powerful alternative to `new Object()`
Object.prototype.foo = "bar";
alert( instance.foo ); // bar
Это все возможно, хотя разумно было бы сделать это ... Я бы сказал, нет, но мнения разные, и я скорее избегаю дебатов;)
В любом случае, просто помните, что свойство prototype
on работает, когда вы new
a function
, в противном случае оно просто становится свойством экземпляра.