Я думал, что у меня есть разумное понимание объекта this
в JavaScript. Когда вы работаете с объектами, обратными вызовами и обоими событиями и обработчиками, у меня не было проблемы с ним с незапамятных времен. Теперь, однако, все изменилось.Закрытие и закрытие этого объекта
Я упал на пятки в любви с JavaScript. Pure JS, то есть не jQuery, prototype.js, dojo ... Так что, естественно, я взял использование закрытий. В некоторых случаях, однако, this
улавливает меня здесь. Возьмите этот фрагмент кода для одного:
function anyFunc(par)
{
//console.log(par);
console.log(this);
}
function makeClosure(func)
{
return function(par)
{
return func(par);
}
}
var close = makeClosure(anyFunc);
close('Foo');
var objWithClosure = {cls:makeClosure(anyFunc),prop:'foobar'};
objWithClosure.cls(objWithClosure.prop);
var scndObj = {prop:'Foobar2'};
scndObj.cls = makeClosure;
scndObj.cls = scndObj.cls(anyFunc);
scndObj.cls(scndObj.prop);
Во всех трех случаях, this
журналы как объект окна. Это легко исправить, конечно:
function makeClosure(func)
{
return function(par)
{
return func.call(this,par);
}
}
Это исправление работает, я положил его здесь, чтобы избегать людей, отвечая на это, не объясняя, что мне нужно знать: почему это ведет так, как это делает здесь?
гарантирует, что вызывающий объект фактически является объектом, к которому принадлежит закрытие. Что я не понимаю, так это: Конечно, this
указывает на объект окна в первом случае, но в других случаях он не должен. Я попробовал logging this
в функции makeClosure перед возвратом, и он сам зарегистрировал сам объект, а не объект window
. Но когда используется фактическое закрытие, this
возвращается к объекту окна. Зачем?
Единственное, что я могу придумать, это то, что, передавая функцию anyFunc
в качестве аргумента, я фактически прохожу window.anyFunc
. Так что я попытался это быстро исправить:
function makeClosure(func)
{
var theFunc = func;
return function(par)
{
theFunc(par);
}
}
с ожидаемыми результатами, this
теперь указывает на объекты, но опять-таки: почему? У меня есть несколько идей (theFunc
- ссылка на функцию в локальной области [this > private: theFunc
]?), Но я уверен, что здесь есть люди с гораздо большим количеством ноу-хау, когда дело доходит до JS, поэтому я надеялся получить больше объяснений или ссылки на статьи стоит читать из них ...
Благодарности
Update
Here's a fiddle, может быть, я оставил что-то, но здесь это регистрирует все виды вещей;)
E dit/Обновление 2
The case that confuses me есть здесь.
Final Редактировать
Хорошо, Это становится довольно грязный пост. Таким образом, чтобы уточнить: То, что я ожидал, было поведение похоже на это:
function makeClosure()
{
function fromThisFunc()
{
console.log(this);
}
return fromThisFunc;
}
var windowContext = makeClosure();
windowContext();
var objectContext = {cls:makeClosure()};
objectContext.cls();
Что привлекло меня, было то, что функция anyFunc
не была объявлена в правильном объеме, и, следовательно, this
указал на объект окна. Я нашел это, прочитав ancient scroll, который я нашел где-то в Интернете.
Но кое-что посложнее произошел потому, что объект функции теперь именуется по globalVar был создан с [[Scope]] собственность ссылки на цепочку областей видимости, содержащую Activation/Variable объект, принадлежащий к контексту выполнения в который был создан (и глобальный объект). Теперь объект Activation/Variable не может быть собран в виде мусора, так как выполнение объекта функции, на которое ссылается globalVar, необходимо будет добавить целую цепочку цепочки из своего свойства [[scope]] в область контекста выполнения, созданного для каждого вызова Это.
Так что мне нужно было сделать, было Упростить, а затем усложнять:
function fromThisFunc()
{
console.log(this);
}
function makeClosure(funcRef)
{
//some code here
return funcRef;
}
Это должно работать, не так ли?
PS: Я за исключением ответа Алнитак, но особая благодарность Феликс Клинг за все терпение и информацию.
Я не получить то, что другой ответ, чем ссылка на глобальное объяснение закрытия может сделайте. Этот курс является отличным чтением и должен устранить все неопределенности: http://ejohn.org/apps/learn/ –
Проблема не в том, что я не закрываю. То, что вызывает головные боли, заключается в том, что я не совсем уверен, что происходит с этим объектом, когда делает замыкания так, как я здесь. –
Я не могу воспроизвести описанную вами ситуацию. Я получаю 'DOMWindow',' Object', 'Object': http://jsfiddle.net/GErkX/, тогда как ваше второе« исправление »дает мне 3 x' DOMWindow': http://jsfiddle.net/tZXQF/ –