Прототип JavaScript ограничен функциями?

o.prototype = {...} Работает, только если o является Функция. Предположим, что у меня есть следующий Код

 conf = {
  a: 2,
  b: 4
 };
 conf.prototype = {
  d: 16
 }

conf.a и conf.b в порядке и возвращают собственные значения. Но conf.d не возвращается 16 скорее, он идет неопределенный. Есть ли любое решение, сосут то основанное на прототипе обобщение, может также быть применен на подобные Объекты.

7
задан Neel Basu 21 January 2010 в 17:20
поделиться

2 ответа

Вы путаете свойство прототипа , которое можно использовать в функциях конструктора , и внутреннее свойство [[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]] ).

21
ответ дан 6 December 2019 в 06:36
поделиться

На самом деле есть два разных вида «прототипа» в JavaScript:

  1. - один - «скрытая» связь, которую каждый объект имеет (давайте использовать [[[Prototype]] , чтобы представить эту скрытую ссылку). Объектные литералы по умолчанию имеют свои скрытые ссылки, указывающие на объект . Прототип , функциональные объекты имеют свою скрытую ссылку, указывающую на функции. Прототип , а массивы имеют их указывание на . Эти скрытые прототипы ссылок не связаны со свойствами с именем «прототип». Вы не можете изменить эти скрытые ссылки, добавив или модифицирую O.Prototype .
  2. Другой состоит в том, что все объекты функции автоматически имеют специальное свойство с именем « прототип ». Это в основном для использования структуры вызова конструктора.

[[[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 помогает починить его.

6
ответ дан 6 December 2019 в 06:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: