Путаница возникает из-за того, что функцию можно использовать и как вызываемую функцию, и как конструктор объекта. Хорошей практикой является не смешивать обе формы, то есть функцию-конструктор не следует использовать в качестве вызываемой функции. В общем случае функция-конструктор имеет первую букву с заглавной буквы (просто по соглашению, чтобы дать подсказку читателю кода). Объектно-ориентированные языки обычно неявно предоставляют ссылку на объект, для которого вызывается метод. В Javascript эта ссылка является ключевым словом this внутри функции. Рассмотрим следующий код.
var obj = {
sum: 0,
add: function(increment) {
this.sum += increment;
return this.sum;
}
};
Когда мы вызываем obj.add(2), интерпретатор или компилятор на любом другом объектно-ориентированном языке будет выполнять внутренний вызов метода add следующим образом:
add(arguments..., [this=obj]) {
//this is the obj reference inside the method
}
add(arguments, obj);
Выше приведен только псевдокод, последний параметр скрыт от нас, и нам не нужно передавать его явно, этот параметр является ссылкой на фактический объект, для которого был вызван метод add(), и доступен через «этот» keyworkd .
В общем, когда мы объявляем функцию вне области видимости объекта, она становится методом (отредактированным**, если он не вложен в другую функцию) глобального объекта (обычно объекта окна). Таким образом, его вызов будет передавать глобальный объект как ссылку "this". В строгом режиме глобальный объект по умолчанию не определен, и любые операции, которые должны выполняться с окном или глобальным объектом, должны выполняться явно. Чтобы мы случайно не изменили глобальный объект.
Когда мы вызываем функцию как конструктор, как показано ниже
var p1 = new Person();
Интерпретатор выполнит код, аналогичный
var newObj = new Object();
Person(arguments..., [this=newObj]) {
//this is the newObj reference inside the method
return this;
}
Person(arugments..., newObj);
Надеюсь, теперь стало немного понятнее.
person
11thdimension
schedule
18.11.2015
this.age = age
? Как вы думаете, что такоеthis
? Почему вы ожидаете, что функция будет что-то регистрировать? Он не содержит оператораconsole.log
.console.log
находится в теле, если внутренняя функция никогда не вызывается. Я не пытаюсь создать новый объект, но вы только что сказали в своем вопросе: Я играю с объектами и конструкторами. - person Felix Kling   schedule 19.11.2015this.age
относится к объектуwindow
, и если это правда (что может быть не так),this
не должно оцениваться какundefined
(я думаю). Однако, если бы это был объект окна,window.age
было быundefined
, что имело бы смысл. Спасибо, что поймали частьconsole.log
. - person Stu   schedule 19.11.2015this.age
относится к объекту окна Я думаю, вы имеете в виду, чтоthis
является объектомwindow
. Как я сказал в своем ответе, если ваш код работает в строгом режиме,this
равноundefined
. И поскольку вы получаете эту конкретную ошибку, похоже, ваш код работает в строгом режиме. Однако, если бы это был объект окна, значение window.age было бы неопределенным, что имело бы смысл. Что ж, после запуска вашей функцииwindow.age
будет равно 5. - person Felix Kling   schedule 19.11.2015