Связь между [[Прототипом]] и prototype в JavaScript

StackOverflow https://stackoverflow.com/questions/383201

  •  23-08-2019
  •  | 
  •  

Вопрос

От http://www.jibbering.com/faq/faq_notes/closures.html :

Примечание:ECMAScript определяет внутреннее свойство [[prototype]] типа internal Object.Это свойство недоступно напрямую с помощью сценариев, но это цепочка объектов, на которые ссылается внутреннее свойство [[prototype]], которое используется при разрешении доступа к свойству;цепочка прототипов объекта.Общедоступное свойство prototype существует, чтобы разрешить назначение, определение и манипулирование прототипами в сочетании с внутренним свойством [[prototype]]. Детали взаимосвязи между to two описаны в ECMA 262 (3-е издание) и выходят за рамки данного обсуждения.

Каковы детали отношений между этими двумя?Я просмотрел ECMA 262, и все, что я там прочитал, это что-то вроде:

Связанный прототип конструктора может ссылаться на программное выражение constructor.prototype,

Собственные объекты ECMAScript имеют внутреннее свойство, называемое [[Prototype]].Значение этого свойства равно либо null, либо object и используется для реализации наследования.

Каждая встроенная функция и каждый встроенный конструктор имеют объект прототипа функции, который является начальным значением выражения Function.prototype

Каждый встроенный объект-прототип имеет объект Object prototype, который является начальным значением выражения Object.prototype (15.3.2.1), в качестве значения его внутреннего свойства [[Прототип]], за исключением объекта сам прототип объекта.

Из этого все, что я делаю вывод, это то, что свойство [[Prototype]] эквивалентно prototype свойство практически для любого объекта.Я ошибаюсь?

Это было полезно?

Решение

Я считаю, что вы правы в большинстве случаев.

Каждый объект имеет скрытую [[Prototype]] имущество, которое используется для наследования.Функции дополнительно имеют общедоступный prototype свойство, которое используется только тогда, когда функция используется в качестве конструктора:Когда объект создается с использованием new, тот [[Prototype]] свойство нового объекта устанавливается в prototype свойство функции, которая была использована в качестве конструктора.

Например.

function C() {}
C.prototype = P1;  
var obj = new C();  // obj.[[Prototype]] is now P1.

Вы можете получить [[Prototype]] использование собственности Object.getPrototypeOf(<obj>).(Этот метод указан в ECMAScript 5.Более старые версии JavaScript не имеют какого-либо стандартного способа чтения [[Prototype]]).

Ты можешь обычно получить доступ к прототипу через конструктор, например:

obj.constructor.prototype == Object.getPrototypeOf(obj) 

Но это не всегда так, поскольку свойство prototype функции конструктора может быть переназначено, но [[Prototype]] объекта не может быть переназначен после создания объекта.Так что, если вы это сделаете:

C.prototype = P2;

тогда

obj.constructor.prototype != Object.getPrototypeOf(obj)

Потому что прототип C это сейчас P2, но [[Prototype]] из obj все еще P1.

Обратите внимание, что это Только функции , которые имеют prototype собственность.Обратите также внимание, что prototype свойство функции не совпадает с [[Prototype]] свойство функции!

Другие советы

Чтобы прямо ответить на ваш вопрос:логически это частная копия объекта prototype свойство его конструктора.Используя метаязык , вот как создаются объекты:

// not real JS

var Ctr = function(...){...};
Ctr.prototype = {...}; // some object with methods and properties

// the object creation sequence: var x = new Ctr(a, b, c);
var x = {};
x["[[prototype]]"] = Ctr.prototype;
var result = Ctr.call(x, a, b, c);
if(typeof result == "object"){ x = result; }
// our x is fully constructed and initialized at this point

На этом этапе мы можем модифицировать прототип, и это изменение будет отражено всеми объектами класса, поскольку они ссылаются на прототип по ссылке:

Ctr.prototype.log = function(){ console.log("...logging..."); };

x.log();  // ...logging..

Но если мы изменим прототип в конструкторе, уже созданные объекты будут продолжать ссылаться на старый объект:

Ctr.prototype = {life: 42};
// let's assume that the old prototype didn't define "life"

console.log(x.life);  // undefined
x.log();              // ...logging...

В полном соответствии со стандартом [[prototype]] недоступен, но Mozilla расширяет стандарт с __proto__ свойство (только для чтения), которое раскрывает обычно скрытый [[prototype]]:

Снова, __proto__ может быть легализован в следующий стандарт ES3.1.

В дополнение к ответу олавка:Некоторые реализации JavaScript (например mozilla - это) разрешить прямой доступ к свойству [[Prototype]]...

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top