试图在javascript中理解`this`

时间:2015-01-07 11:36:39

标签: javascript scope

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

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无效?

3 个答案:

答案 0 :(得分:3)

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

它不像C#这样的语言,this引用类的当前实例,无论你是否在另一种方法中。

答案 1 :(得分:1)

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内声明,而不是在那里声明的。

  

修改

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

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

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

    然后调用

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

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

答案 2 :(得分:0)

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

这也是一些库为方法采用对象上下文的原因,即。茉莉花的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();
});