为什么当调用一个函数时,第一个this是父对象,但在随后的函数调用中,this是指窗口对象
Why when invoking a function is the first this the parent object, but on a subsequent function call this refers to the window object?
当最初调用一个函数时,第一个被调用的函数中的第一个this
指向父对象foo
,但在第一个函数调用的后续函数中,this
指向窗口对象?
var foo = (function Obj(){
var t = this;
return {
getThis: getThis,
getSecondThis: getSecondThis
};
function getThis(){
console.log(this);
console.log(t);
getSecondThis()
return false;
}
function getSecondThis(){
console.log(this);
console.log(t);
return false;
}
})();
foo.getThis();
如果我将调用从getSecondThis()
更改为this.getSecondThis()
,则getSecondThis()
中的this
指的是父对象foo
,请参阅下面的代码
var foo = (function Obj(){
var t = this;
return {
getThis: getThis,
getSecondThis: getSecondThis
};
function getThis(){
console.log(this);
console.log(t);
this.getSecondThis() //line edited
return false;
}
function getSecondThis(){
console.log(this);
console.log(t);
return false;
}
})();
foo.getThis();
getSecondThis()
在父对象foo
的范围内,但是当第二次调用时没有指定this
时返回window。
这只是JS绑定调用上下文的方式:JS绑定上下文(this
引用)-hoc。含义:根据它被调用的方式、位置和方式,this
将引用不同的对象。
在此之前,我已经详细解释了这一点,并在底部的链接答案中找到
this
指向拥有这个方法的对象。然而,正如Pointy在注释中指出的那样:一个对象不能拥有另一个对象。对象可以被另一个对象的一个或多个属性引用。
JS会设置this
引用拥有该函数的对象。但是如果将对象赋值给一个变量,那么让this
指向同一个对象就没有意义了。考虑将函数作为函数参数传递的情况(jQuery中的回调等)。您可能希望this
引用新的上下文(在jQ事件处理程序中当然是这种情况!)。如果没有提供上下文,JS将this
引用默认为全局对象。
可以显式地使用Function.prototype.bind
调用将函数绑定到给定的上下文中。如果您想为单个调用指定上下文,您可以使用Function.prototype.call(context, arg1, arg2);
或Function.prototype.apply(context, [args]);
大多数大型项目(例如jQ之类的工具包)通过利用闭包作用域来解决这个问题。例如,使用模块模式是控制上下文的一种常见且简单的方法。我也解释了这一点,并配有图表来说明发生了什么:)
一些例子/谜题,使这更容易遵循或更有趣:
var obj = (function()
{//function scope
'use strict';//this will be null, instead of global, omit this and this can be window
var obj = {},
funcOne = function()
{
console.log(this, obj, this === obj);
funcTwo(this);
obj.funcTwo();
obj.funcTwo(this);
obj.funcTwo(obj);
},
funcTwo = function(that)
{
console.log(this, obj, this === obj, this === that, that === obj);
};
obj.funcOne = funcOne;
obj.funcTwo = funcTwo;
return obj;//is assigned to the outer var
}());
obj.funcOne();
//output:
//- first logs itself twice, then true
//then calls made in funcOne:
funcTwo()
console.log(this, obj, this === obj, this === that, that === obj);
//- this: undefined (omit 'use strict' and it'll be window), obj,
// this === obj => false, this === that => false, that === obj => true
obj.funcTwo();
console.log(this, obj, this === obj, this === that, that === obj);
//logs obj twice, because obj.funcTwo means the context === obj
//this === obj is true (of course)
//that is undefined, so this === that and that === obj are false
//lastly
obj.funcTwo(this);
obj.funcTwo(obj);
你应该能算出来。你知道funcOne
被执行的上下文,并且你知道作为obj
的方法调用funcTwo
的效果是什么
经验法则:
我犹豫了一下,因为它远不准确,但有8/10的情况。假设没有代码通过bind
、call
和apply
干扰上下文,您可以使用以下技巧计算上下文:
someObject.someMethod();
/' ||
|===this===|
//another object:
var obj2 = {
borrowed: someObject.someMethod,
myOwn: function()
{
this.borrowed();
}
};
obj2.myOwn();//this === obj2 (as explained above),
''
'==> this.borrowed === obj2.borrowed
''
'==> ~= someObject.someMethod.call(obj2);//function is executed in context of obj2
//simple vars
var alias = someObject.someMethod;//assign to var
alias();//no owner to be seen?
||
?<==|
//non-strict mode:
[window.]alias();
/' implied ||
|| ||
|==<this>===|
//strict mode
alias.call(undefined);//context is undefined
- javascript中对象构造函数中的var属性与this.properties
- 定义this.properties或objectName.properties的javascript JSON对象
- 如何使用(this)访问Angular 2 http rxjs catch函数中的对象属性
- Javascript 对象和 this 关键字
- jquery$(this)对象缺少问题
- Javascript对象来获取父方法的this
- 如何绑定“;这个“;在$http.post中->在AngularJS中解析/拒绝?(现在this=Window对象
- 将“this”关键字发送到对象中
- jQuery双对象构造函数-例如$($(this))
- ui.selectmenu投掷'this.newelement.0'为null或不是对象
- 警告 - 全局 THIS 对象的危险使用
- $.each 中的“this”,当需要使用“this”访问对象的函数时
- Javascript对象文字,如何使用“this”来引用对象中的变量
- 为什么当我尝试将函数绑定到自身时,“this”对象仍然引用窗口
- TypeScript:在对象文字字段中的访问器中访问外部“this”
- 在将对象传递给数组时,在 this.x 上给“x”一个变量值
- 将对象this发送到不带参数的函数
- 使用HTML5音频和jQuery对调用对象(this)的引用
- Javascript在对象中使用绑定,我如何访问对象this
- 无法使用“this”访问对象.“this”指向“窗口”对象