Закрытие JavaScript и этот объект
Я думал, что у меня есть разумное пониманиеthis
объект в JavaScript. При работе с объектами, обратными вызовами, а также событиями и обработчиками у меня не было проблем с незапамятных времен. Однако теперь все изменилось.
Я влюбился в JavaScript. Чистый JS, то есть не jQuery, prototype.js, dojo ... Естественно, я привык использовать замыкания. В некоторых случаях, однако,this
застает меня врасплох здесь Возьмите этот фрагмент для одного:
<code>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); </code>
Во всех трех случаяхthis
регистрируется как объект окна. Конечно, это легко исправить:
<code>function makeClosure(func) { return function(par) { return func.call(this,par); } } </code>
This fix works, I put it here to avoid people answering this, without explaining what I need to know: why is this behaving the way it does here?
гарантирует, что вызывающий объект является объектом, которому принадлежит замыкание. Что я не понимаю, так это:
Конечно же,this
указывает на объект окна в первом случае, но в других случаях он не должен '. Я пробовал войтиthis
в функции makeClosure непосредственно перед возвратом, и он регистрировал сам объект, а неwindow
объект. Но когда фактическое закрытие используется,this
вернулся к указанию на объект окна. Зачем?
Единственное, о чем я могу думать, это то, что, передаваяanyFunc
в качестве аргумента я фактически передаюwindow.anyFunc
, Итак, я попробовал это быстрое решение:
<code>function makeClosure(func) { var theFunc = func; return function(par) { theFunc(par); } } </code>
С ожидаемыми результатами,this
теперь указывает на объекты, но опять же: почему? У меня есть несколько идей (theFunc
ссылка на функцию в локальной области видимости [this > private: theFunc
]?), но я уверен, что здесь есть люди с гораздо большим ноу-хау, когда дело доходит до JS, поэтому я надеялся получить больше объяснений или ссылок на статьи, которые стоит прочесть у них ...
Спасибо
Update
Здесь скрипка, может быть, я что-то упустил, но здесь это регистрирует все виды вещей;)
Edit/Update 2
Дело, которое меня смущает это здесь.
Final Edit
Хорошо, это довольно грязный пост. Итак, чтобы уточнить: то, что я ожидал, было поведение, подобное этому:
<code>function makeClosure() { function fromThisFunc() { console.log(this); } return fromThisFunc; } var windowContext = makeClosure(); windowContext(); var objectContext = {cls:makeClosure()}; objectContext.cls(); </code>
Что меня поймало, так это то, что функцияanyFunc
не был объявлен в правильной области, и, следовательно,this
указал на окно объекта. Я узнал об этом, прочитавдревний свиток Я нашел где-то в Интернете.
But something a little more complicated has happened because the function object now referred to by globalVar was created with a [[scope]] property referring to a scope chain containing the Activation/Variable object belonging to the execution context in which it was created (and the global object). Now the Activation/Variable object cannot be garbage collected either as the execution of the function object referred to by globalVar will need to add the whole scope chain from its [[scope]] property to the scope of the execution context created for each call to it.
Так что мне нужно было упростить, а не усложнить вещи:
<code>function fromThisFunc() { console.log(this); } function makeClosure(funcRef) { //some code here return funcRef; } </code>
Это должно работать, верно?
PS: я буду, кроме ответа Алнитак, но отдельное спасибо Феликсу Клингу за все терпение и информацию.