简体   繁体   English

试图在javascript中理解`this`

[英]Trying to understand `this` in javascript

I have an object with a number of functions: 我有一个具有许多功能的物体:

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

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

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

So if I call someScopeScopedObject.myFunction2 that works fine 因此,如果我调用someScopeScopedObject.myFunction2可以正常工作

But If I do someScopeScopedObject.init(someScopeScopedObject.myFunction2) then I get an error that this.myFunction1 is undefined 但是,如果我执行someScopeScopedObject.init(someScopeScopedObject.myFunction2)则会收到错误this.myFunction1 is undefined

Why is this not valid when I call into the function that way? 当我以这种方式调用函数时,为什么this无效?

The keyword this refer's to the functions scope. this是功能范围的关键字。 Not the global scope. 不是全球范围。 You declare a function called myFunction2 , the this refers to the scope of this function and not the scope in which this function is declared. 您声明调用的函数myFunction2 ,在this指的是这个功能的范围,而不是在这个函数声明的范围。

It isn't like in languages, like C#, where this refers to the current instance of the class, whether you are in one another method. 它不喜欢的语言,如C#,其中this指的是类的当前实例,无论你是在一个另一种方法。

this refers to the function in which it is declared, So in your example, this是指在其中声明的函数,因此在您的示例中,

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

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

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

myFunction1 is not declared inside myFunction2, so myFunction1没有在myFunction2内部声明,因此

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

is not possible, because this.myFunction1(); 这是不可能的,因为this.myFunction1(); tries to call method myfunction1 which should be declared inside myfunction1 which is not declared there. 尝试调用方法myfunction1,该方法应在未在其中声明的myfunction1内部声明。

Edit: 编辑:

  1. someScopeScopedObject.myFunction2(); is possible because you are calling the method myFunction1 which is defined inside someScopeScopedObject 之所以可行是因为您正在调用在someScopeScopedObject内部定义的方法myFunction1

  2. someScopeScopedObject.init(someScopeScopedObject.myFunction2); is not possible because, you pass someScopeScopedObject.myFunction2 as a callback function in this case here to the init function, 这是不可能的,因为在这种情况下,您将someScopeScopedObject.myFunction2作为回调函数传递给了init函数,

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

It then calls 然后调用

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

here you refer this.myFunction1(); 在这里您引用this.myFunction1(); --- This doen not exist, since you are refering to myfunction1 defined inside myfunction2, which is not! ---这个不存在,因为您引用的是在myfunction2内定义的myfunction1,这不是!

When you pass myFunction2 as an argument to something, it loses the reference to the object it belongs to. 当将myFunction2作为参数传递给某物时,它将丢失对它所属对象的引用。 this now refers to the function itself, and not someScopeScopedObject , hence your problem :) 现在this是指函数本身,而不是someScopeScopedObject ,因此是您的问题:)

This is also why some libraries take an object context for methods, ie. 这也是为什么某些库采用对象上下文作为方法的原因。 jasmine's spyOn(someScopeScopedObject, "myFunction2") , to keep the scoping correct. 茉莉花的spyOn(someScopeScopedObject, "myFunction2") ,以保持作用域正确。

An example work-around (like the one used by jasmine) could look like this: 一个变通方法示例(例如茉莉花使用的变通方法)可能如下所示:

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

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

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

This would allow you to do the following: 这将允许您执行以下操作:

someScopeScopedObject.init(someScopeScopedObject, "myFunction2");

This is not the prettiest. 这不是最漂亮的。 Alternatively, you can bind the object to the function (so the scope stays the same). 或者,您可以将对象绑定到函数(因此作用域保持不变)。 This assumes your original code in someScopeScopedObject : 这假定您的原始代码在someScopeScopedObject

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

Neither of these are pretty, and, really, that's because it is weird to externally feed a function belonging to an object as a callback to that object. 这些都不是很漂亮,实际上,这是因为从外部提供属于对象的函数作为对该对象的回调很奇怪。

The best solution might be: 最好的解决方案可能是:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM