o.prototype = {...} Работает, только если o является Функция. Предположим, что у меня есть следующий Код
conf = {
a: 2,
b: 4
};
conf.prototype = {
d: 16
}
conf.a и conf.b в порядке и возвращают собственные значения. Но conf.d не возвращается 16 скорее, он идет неопределенный. Есть ли любое решение, сосут то основанное на прототипе обобщение, может также быть применен на подобные Объекты.
Вы путаете свойство прототипа
, которое можно использовать в функциях конструктора , и внутреннее свойство [[Prototype]]
. .
Все объекты имеют это внутреннее свойство [[Prototype]]
, и только оператор new
, когда вы вызываете его с помощью функции конструктора, может устанавливать его (через [[Construct]]
внутренняя операция).
Если вы хотите иметь прототипное наследование с экземплярами объектов (без использования конструкторов), вам нужен метод Крокфорда Object.create
(этот метод теперь является частью недавно утвержденного ECMAScript 5th Edition):
// Check if native implementation available
if (typeof Object.create !== 'function') {
Object.create = function (o) {
function F() {} // empty constructor
F.prototype = o; // set base object as prototype
return new F(); // return empty object with right [[Prototype]]
};
}
var confProto = {
d: 16
};
var conf = Object.create(confProto);
conf.a = 2;
conf.b = 4;
В приведенном выше коде conf
будет иметь три своих члена, но только a
и b
будут физически существовать на нем:
conf.hasOwnProperty('a'); // true
conf.hasOwnProperty('b'); // true
conf.hasOwnProperty('d'); // false
Потому что d
существует в conf [[Prototype]]
( confProto
).
Аксессоры свойств , .
и []
отвечают за разрешение поиска свойств, если необходимо, в цепочке прототипов (с помощью внутреннего метода [[Get]]
).
На самом деле есть два разных вида «прототипа» в JavaScript:
[[[Prototype]]
, чтобы представить эту скрытую ссылку). Объектные литералы по умолчанию имеют свои скрытые ссылки, указывающие на объект . Прототип
, функциональные объекты имеют свою скрытую ссылку, указывающую на функции. Прототип
, а массивы имеют их указывание на
. Эти скрытые прототипы ссылок не связаны со свойствами с именем «прототип». Вы не можете изменить эти скрытые ссылки, добавив или модифицирую O.Prototype
. прототип
». Это в основном для использования структуры вызова конструктора. [[[Prototype]] [
используется для поиска свойств (таких как родитель в классической иерархии), всякий раз, когда свойство не может быть найдено в объекте, его [[прототип]]
ищется вместо этого. Один сценарий использования: скажем, вы хотели бы добавить свойство всем объектам, вы можете просто добавить его в Object.Prototype
, который автоматически применится ко всем объектам, поскольку все объекты как-то имеют Object. Прототип
как их [[прототип]]
корень цепи.
Давайте вернемся к функциям объектов « Prototype
свойство ». Это полезно только при использовании с оператором NEW
. Возьмите следующий фрагмент кода в качестве примера:
function F() {} // function declaration
// F now has a property named "prototype"
var f = new F(); // use "new" operator to create a new function object based on F
Что новый F ()
делает выше, должен сначала создать новый объект функции, установить [[Prototype]]
(скрытая ссылка ) этого вновь созданного объекта функциональной функции f.prototype
, а затем верните новый объект функции. Вероятно, это то, что вы уже понимаете, что работает для объектов функций.
Помните, что я сказал, что мы не можем изменить объекты [[прототип]]
? Ну, по крайней мере, не напрямую. Crockford's Object.Create
Функция делает только что, используя тот факт, что оператор новый
может помочь установить [[Prototype]]
для нас. Так, используя Object.Create
, вы получаете намеренно указать, где следует указывать скрытая ссылка вашего нового объекта. (Некоторые чувствуют, что указывают на то, кто является вашим родительским классом)
В вашем примере CONT
является объектом буквальным и Conf.Prototype
не очень полезно. Вот еще одна версия, использующая классический стиль:
function ConfBase() {}
ConfBase.prototype.d = 16;
var conf = new ConfBase();
conf.a = 2;
conf.b = 4;
document.writeln(conf.a);
document.writeln(conf.b);
document.writeln(conf.d);
по сравнению с ответом @CMS, я предпочитаю использовать Object.Create
. Но по сути 2 стиля используют один и тот же основной механизм, просто это Object.Create
помогает починить его.