Значение этого в наследовании прототипа - PullRequest
2 голосов
/ 15 июля 2009

Если у меня есть:

var Shape = function()
{ 
    this.toString_ = function() { alert(this.UL)}
}

Shape.prototype.UL = "<UL></UL>"

var _2D = function() { this.name = "_2D"}

_2D.prototype = new Shape()

var i = new _2D()

i.toString_()

когда я вызываю i.toString_(), движок JS пытается найти, если у меня есть функция toString_, но я не могу ее найти, переходит в _2D.prototype (экземпляр Shape) и находит функцию

Здесь this ссылается на экземпляр Shape?

Затем он выполняет функцию и находит в предупреждении this.UL, теперь не находя его, он переходит к Shape.prototype, обладающему этим свойством ...

Теперь, кто такой this?

Может кто-нибудь объяснить мне значение this в цепочке наследования?

Начинается ли с i ... и заканчивается Shape.prototype?

Confused!

Ответы [ 2 ]

2 голосов
/ 15 июля 2009

Наследование прототипов в JavaScript работает следующим образом.

Каждый объект Function имеет свойство с именем «prototype». Когда объект создается с использованием «new», среда выполнения выделяет пустой объект и устанавливает для его свойства «prototype» то же значение, что и для свойства «prototype» функции конструктора. Стандартный JS не имеет возможности обновить прототип этого пустого объекта впоследствии. Свойства могут быть добавлены или удалены из этого объекта, либо в функции конструктора, либо позже. Значение по умолчанию:

MyFunction.prototype = Object.prototype

Всякий раз, когда к свойству обращаются с помощью «this. [Property]», среда выполнения сначала проверяет, есть ли у свойства «this», созданного выше, свойство. Если не найдено, то среда выполнения просматривает «this.prototype», затем «this.prototype.prototype» и т. Д. До тех пор, пока не будет проверен Object.prototype. Если его не найти, в качестве значения свойства будет возвращено «неопределенное».

obj -> obj.prototype -> obj.prototype.prototype -> Object.prototype

Например,

var myPrototype = { prop : "ABC" }
function MyConstructor()
{
}
MyConstructor.prototype = myPrototype
var o = new MyConstructor()
alert( o.prop )

В приведенном выше описании при разрешении «o.prop» среда выполнения сначала ищет в «o» свойство «prop». Не найдя его на «o», среда выполнения смотрит на «myPrototype». Найдя его там, возвращается значение «ABC».

Обратите внимание, что ссылка "this" всегда относится к объекту, созданному выше (например, "o"). Таким образом, если бы вы присвоили значение свойству прототипа, используя «this», среда выполнения фактически создаст новое свойство с таким именем и поместит его в объект, на который ссылается «this», а не обновление значения в прототипе, таким образом, «затеняя» исходное значение. Чтобы изменить значение прототипа, необходимо напрямую ссылаться на объект прототипа либо через «this.prototype». или с помощью другой ссылки на этот объект, скажем «thePrototypeObject. [property]», при условии, что для объекта-прототипа назначена переменная.

o.prop = "DEF"
alert( o.prop )
alert( myPrototype.prop )

В этом случае оператор присваивания создает новое свойство с именем «prop» для «o» . Итак, первое предупреждение печатает «DEF», тогда как второе печатает «ABC».

var o = new MyConstructor()
myPrototype.prop = "DEF"
alert( o.prop )
alert( myPrototype.prop )

В в этом случае свойство «prop» исходного прототипа обновляется, поэтому оба они выводят одно и то же значение («ABC»).

В вашем примере выше,

var Shape = function()
{ 
    this.toString_ = function() { alert(this.UL)}
}
Shape.prototype.UL = "<UL></UL>"
var _2D = function() { this.name = "_2D"}
_2D.prototype = new Shape()
var i = new _2D()

i.toString_()

Цепочка прототипов выглядит следующим образом:

Shape.prototype -> Object.prototype

Object.prototype.UL = "<UL></UL>"

_2D.prototype -> (new Shape) -> Object.prototype

i.prototype -> (new Shape) -> Object.prototype

Итак, при разрешении "toString_ ()" среда выполнения проверяет сначала "i" и, не найдя его там, ищет объект (новый Shape). Находя его там, он вызывает «toString_ ()», передавая «i» как «this». При разрешении "this.UL" среда выполнения сначала смотрит на "i", затем (новая форма), затем на "Object.prototype", наконец, возвращая найденное там значение.

1 голос
/ 15 июля 2009

Просто добавьте:

alert(this instanceof Shape);
alert(this instanceof _2D);

в методе toString_, и вы увидите, какой this у вас есть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...