您好我有以下我试图运行的JavaScript代码。我的目标是在JavaScript中掌握this
在不同范围和不同类型的调用中的含义。
如果您查看下面的代码:我有一个内部匿名函数,它被分配给innerStuff
变量。在那个匿名函数中this
指向window
对象而不是外部函数对象或其他任何东西。事件虽然它仍然可以访问函数的变量。
无论如何,我不确定,为什么会这样;但是如果你查看下面的代码,我会以this
的形式将that
传递给innerStuff
,它可以正常工作并在控制台中打印带有doofus
属性的对象。
var someStuff = {
doofus:"whatever",
newF: function()
{
var that = this;
console.log(that);
var innerStuff = function(topThis){
console.log(topThis);
};
return innerStuff(that);
}
}
someStuff.newF();
现在我只是改变了一点代码。而不是将其分配给innerStuff
,我只是通过调用它直接返回该函数,如下所示:
var someStuff = {
doofus:"whatever",
newF: function()
{
var that = this;
console.log(that);
return function(that){
console.log(that);
}();
}
}
someStuff.newF();
这为内部匿名函数打印undefined。是因为作为参数传递的that
与外部函数中定义的that
之间存在冲突吗?
我认为参数会覆盖可见性。为什么价值不会保留?
这完全令人困惑。
另一方面,如果我没有通过that
,而只是使用它,因为可见性存在,结果是正确的并且符合预期。
我错过了什么?它是变量之间的冲突,存在于相同的范围内吗?
是否有充分的理由,内部函数this
绑定到window
对象?
答案 0 :(得分:9)
this
指的是您调用方法的对象。如果您将函数调用为someObject.functionName(args)
,则this
将绑定到该对象。如果您只是调用一个裸函数,就像functionName(args)
一样,那么this
将绑定到window
对象。
在第二个示例中的newF
内部,您正在隐藏内部函数中的that
变量,但没有将任何内容传递给它,因此未定义。
var that = this;
console.log(that);
return function(that){
console.log(that);
}();
如果你想要一些与你的第一个例子相同的东西(将that
传递给内部函数),你可能需要以下内容:
var that = this;
console.log(that);
return function(that){
console.log(that);
}(that);
或者下面,如果你不想遮蔽它并只使用外部函数的绑定:
var that = this;
console.log(that);
return function(){
console.log(that);
}();
答案 1 :(得分:1)
在第二个示例中,当您调用匿名函数时,未定义参数that
(您没有向其传递任何内容。)您可以这样做:
newF: function()
{
var that = this;
console.log(that);
return function(that){
console.log(that);
}(that); // note that we are passing our 'that' in as 'that'
}
这将保持变量的正确值。
但是,既然您正在考虑上面的var that
,那么您也可以删除函数参数:
newF: function()
{
var that = this;
console.log(that);
return function(){
console.log(that);
}(); // 'that' is referenced above.
}
至于为什么匿名函数window
为this
:无论何时调用没有上下文的函数(即somef()
vs context.somef()
)this
将指向window
对象。
您可以覆盖该内容并使用.apply(context, argumentsArray)
or .call(context, arg1, arg2, arg3)
在函数上传递this
。一个例子:
newF: function()
{
console.log('Outer:', this);
var innerF = function(){
console.log('Inner:', this);
};
return innerF.apply(this,arguments);
}
答案 2 :(得分:1)
在您的第一个代码示例中,匿名函数虽然在作为someStuff
对象成员的函数中声明,但它不是someStuff
对象的成员。因此,该函数中的this
是对窗口对象的引用。如果您想调用匿名函数并控制this
引用,则可以执行以下操作:
var someStuff = {
doofus:"whatever",
newF: function()
{
var that = this;
console.log(that);
var innerStuff = function(){
console.log(this);
};
return innerStuff.apply(this);
}
}
someStuff.newF();
在第二个示例中,您实际创建了一个匿名函数,执行它,然后返回匿名函数返回的值。但是,您的匿名函数没有返回任何内容。此外,您有一个变量名称冲突。你可以这样做:
var someStuff = {
doofus:"whatever",
newF: function()
{
var that = this;
console.log(that);
return function(){
console.log(that);
return true;
}();
}
}
someStuff.newF();
我添加了返回true,因为你的函数应该返回一些东西,因为正在执行它的函数返回匿名函数的返回值。它是返回true还是false或字符串或对象或其他任何内容取决于方案。