嵌套函数中的Javascript“this”指针

IT技术 javascript function nested this
2021-02-03 03:32:28

我有一个关于如何在嵌套函数场景中处理“this”指针的问题。

假设我将以下示例代码插入到网页中。调用嵌套函数“doSomeEffects()”时出现错误。我检查了 Firebug,它表明当我在那个嵌套函数中时,“this”指针实际上指向全局“window”对象——这是我没想到的。我一定没有正确理解某些东西,因为我认为自从我在对象的函数中声明嵌套函数后,它应该具有与函数相关的“本地”范围(即“this”指针将指代对象本身,例如在我的第一个“if”语句中如何)。

任何指针(无双关语)将不胜感激。

var std_obj = {
  options : { rows: 0, cols: 0 },
  activeEffect : "none",
  displayMe : function() {

    // the 'this' pointer is referring to the std_obj
    if (this.activeEffect=="fade") { }

    var doSomeEffects = function() {

      // the 'this' pointer is referring to the window obj, why?
      if (this.activeEffect=="fade") { }

    }

    doSomeEffects();   
  }
};

std_obj.displayMe();
6个回答

在 JavaScript 中,this对象实际上基于您如何进行函数调用。

一般来说,有三种方法可以设置this对象:

  1. someThing.someFunction(arg1, arg2, argN)
  2. someFunction.call(someThing, arg1, arg2, argN)
  3. someFunction.apply(someThing, [arg1, arg2, argN])

在上述所有示例中,this对象都是someThing. 调用没有前导父对象的函数通常会得到全局对象,这在大多数浏览器中表示该window对象。

this.doSomeEffects();根据您的回答更改了代码,但仍然不起作用。为什么?
2021-03-21 03:32:28
@Arashsoftthisthis.doSomeEffects()std_obj正如上面的答案所解释的,如果一个函数没有对象引用,那么它就是this一个窗口对象。
2021-03-28 03:32:28

由于这似乎是同类问题中投票率最高的问题之一,让我补充一下,经过这么多年,使用箭头函数的 ES6 解决方案:

var std_obj = {
  ...
  displayMe() {
    ...
    var doSomeEffects = () => {
                        ^^^^^^^    ARROW FUNCTION    
      // In an arrow function, the 'this' pointer is interpreted lexically,
      // so it will refer to the object as desired.
      if (this.activeEffect=="fade") { }
    };
    ...    
  }
};

this不是闭包作用域的一部分,它可以被认为是在调用点绑定的函数的附加参数。如果该方法不是作为方法调用,则全局对象将作为this. 在浏览器中,全局对象与window. 例如,考虑以下函数,

function someFunction() {
}

和以下对象,

var obj = { someFunction: someFunction };

如果您使用方法语法调用该函数,例如,

obj.someFunciton();

那么this必然是obj

如果直接调用 someFunction() ,例如,

someFunction();

thenthis绑定到全局对象,即window.

最常见的解决方法是将其捕获到闭包中,例如,

displayMe : function() {      

    // the 'this' pointer is referring to the std_obj      
    if (this.activeEffect=="fade") { }      
    var that = this;  
    var doSomeEffects = function() {      

      // the 'this' pointer is referring to global
      // that, however, refers to the outscope this
      if (that.activeEffect=="fade") { }      
    }      

    doSomeEffects();         
 }      

要理解这个问题,请尝试获取以下代码段的输出

var myObject = {
    foo: "bar",
    func: function() {
        var self = this;
        console.log("outer func:  this.foo = " + this.foo);
        console.log("outer func:  self.foo = " + self.foo);
        (function() {
            console.log("inner func:  this.foo = " + this.foo);
            console.log("inner func:  self.foo = " + self.foo);
        }());
    }
};
myObject.func();

上面的代码将向控制台输出以下内容:

outer func:  this.foo = bar
outer func:  self.foo = bar
inner func:  this.foo = undefined
inner func:  self.foo = bar

在外部函数中,this 和 self 都引用 myObject,因此都可以正确引用和访问 foo。

但是,在内部函数中,this 不再引用 myObject。因此, this.foo 在内部函数中是未定义的,而对局部变量 self 的引用保留在作用域中并可在那里访问。(在 ECMA 5 之前,内部函数中的 this 将引用全局窗口对象;而在 ECMA 5 之前,内部函数中的 this 将是未定义的。)

为什么会这样?
2021-03-28 03:32:28
@raneshu“使用严格”,this不再指窗口
2021-03-30 03:32:28
在内部函数中,this指的是 window 对象(在浏览器环境中)或 GLOBAL 对象(在 node.js 环境中)
2021-04-02 03:32:28

外壳变量和“这个”之间有区别。“this”实际上是由函数的调用者定义的,而显式变量在称为外壳的函数声明块中保持完整。请参阅以下示例:

function myFirstObject(){
    var _this = this;
    this.name = "myFirstObject";
    this.getName = function(){
       console.log("_this.name = " + _this.name + " this.name = " + this.name);  
    }
}

function mySecondObject(){
    var _this = this;
    this.name = "mySecondObject";
    var firstObject = new myFirstObject();
    this.getName = firstObject.getName
}

var secondObject = new mySecondObject();
secondObject.getName();

你可以在这里试试:http : //jsfiddle.net/kSTBy/

您的函数中发生的事情是“doSomeEffects()”,被显式调用,这意味着上下文或函数的“this”是窗口。如果“doSomeEffects”是一个原型方法,例如 this.doSomeEffects 上的“myObject”,那么 myObject.doSomeEffects() 将导致“this”成为“myObject”。

对于懒惰和不耐烦的人,这个演示记录: _this.name = myFirstObject this.name = mySecondObject
2021-03-13 03:32:28