试图理解 javascript 中的 `this`

Trying to understand `this` in javascript

我有一个具有多种功能的对象:

var someScopeScopedObject = {
  myFunction1: function () {
    console.log('foo');
  },

  myFunction2: function () {
    this.myFunction1();
  }

 init: function (callback) {
    callback();
  }
}

所以如果我调用 someScopeScopedObject.myFunction2 就可以了

但是如果我这样做 someScopeScopedObject.init(someScopeScopedObject.myFunction2) 然后我得到一个错误 this.myFunction1 is undefined

为什么当我以这种方式调用函数时 this 无效?

关键字this指的是函数作用域。不是全局范围。您声明一个名为 myFunction2 的函数,this 指的是此函数的作用域,而不是声明此函数的作用域。

它不像 C# 这样的语言,其中 this 指的是 class 的当前实例,无论您是在另一个方法中。

this指的是声明的函数, 所以在你的例子中,

var someScopeScopedObject = {
  myFunction1: function () {
    console.log('foo');
  },

  myFunction2: function () {
    this.myFunction1();
  }

 init: function (callback) {
    callback();
  }
}

myFunction1 没有在 myFunction2 中声明,所以

` myFunction2: function () {
        this.myFunction1();
      }.

是不可能的,因为 this.myFunction1(); 试图调用应该在 myfunction1 中声明的方法 myfunction1 而没有在那里声明。

Edit:

  1. someScopeScopedObject.myFunction2(); 可能的 因为您正在调用在 someScopeScopedObject

    [= 中定义的方法 myFunction1 47=]
  2. someScopeScopedObject.init(someScopeScopedObject.myFunction2); 不可能 因为,在这种情况下,您将 someScopeScopedObject.myFunction2 作为回调函数传递给 init 函数,

init: function (callback) { callback(); }

然后调用

myFunction2: function () { this.myFunction1(); }

这里你指的是 this.myFunction1();--- 这不存在,因为你指的是在 myfunction2 中定义的 myfunction1,而它不存在!

当您将 myFunction2 作为参数传递给某物时,它会丢失对其所属对象的引用。 this 现在指的是函数本身,而不是 someScopeScopedObject,因此你的问题 :)

这也是为什么一些库为方法采用对象上下文的原因,即。 jasmine 的 spyOn(someScopeScopedObject, "myFunction2"),以保持范围的正确性。

一个变通方法示例(如 jasmine 使用的变通方法)可能如下所示:

var someScopeScopedObject = {
  myFunction1: function () {
    console.log('foo');
  },

  myFunction2: function () {
    this.myFunction1();
  },

  init: function (context, callbackName) {
    context[callbackName]();
  }
}

这将允许您执行以下操作:

someScopeScopedObject.init(someScopeScopedObject, "myFunction2");

这不是最漂亮的。或者,您可以将对象绑定到函数(因此作用域保持不变)。这假设您的原始代码在 someScopeScopedObject:

someScopeScopedObject.init(someScopeScopedObject.myFunction2.bind(someScopeScopedObject));

这些都不漂亮,而且,实际上,那是因为从外部 将属于某个对象的函数作为对该对象的回调提供是很奇怪的。

最佳解决方案可能是:

someScopeScopedObject.init(function() {
    someScopeScopedObject.myFunction2();
});