如何从嵌套函数引用类变量/方法?

时间:2017-05-28 13:23:27

标签: javascript class ecmascript-6



class Foo {
  constructor() {
    this.foobar = "foobar";
  }
  bar() {
    let _this = this;
    return function() {
      try {
        alert("Attempt 1: "+foobar);//ReferenceError: foobar is not defined
        myMethod();
      } catch(err) {console.log(err);}
      try {
        alert("Attempt 2: "+this.foobar);//TypeError: this is undefined
        this.myMethod();
      } catch(err) {console.log(err);}
      try{
        alert("Attempt 3: "+_this.foobar);//Works!
        _this.myMethod();
      } catch(err) {console.log(err);}
    }();
  }
  myMethod() {
    alert("myMethod()");
  }
}
new Foo().bar();




上面的例子非常简单 - bar()里面的匿名函数最初是一个jQuery调用,但是为了这个问题,我没有包含它。

为什么尝试1和2不起作用?我是否必须使用_this技巧来引用类变量/方法? 如何从嵌套函数引用类变量/方法?

3 个答案:

答案 0 :(得分:0)

您是否熟悉this关键字在JavaScript中的工作原理?它的值取决于函数的调用方式,而不是函数的定义方式。例如,如果您执行以下操作:

var dog = {
  greeting:"woof",
  talk:function (){
    console.log(this.greeting);
  }
};

var cat={
  greeting:"meow",
  talk:dog.talk
};

dog.talk();
cat.talk();

您将看到,当将talk函数作为对象的方法调用时,该对象将用作this的值。

ES6类也是如此,其中类方法仍然是JavaScript函数,而决定this值的规则仍然适用。如果您想避免声明辅助变量,您应该考虑使用bind

var mammal = {
  greeting:"<noise>",
  getTalk:function (){
    return function(){
      console.log(this.greeting);
    };
  },
  getTalkBinded:function (){
    return (function(){
      console.log(this.greeting)
    }).bind(this);
  }
};

var dog={
  greeting:"woof",
  talk:mammal.getTalk(),
  talkBinded:mammal.getTalkBinded()
};

var cat={
  greeting:"meow",
  talk:mammal.getTalk(),
  talkBinded:mammal.getTalkBinded()
};

dog.talk();
cat.talk();
dog.talkBinded();
cat.talkBinded();

答案 1 :(得分:0)

您正在返回自执行函数执行结果,并在该函数执行期间this全局上下文(而不是您的类对象)。使其工作时使用() => {}()箭头函数调用语法,因为它捕获当前上下文,或function() { }.bind(this)()

答案 2 :(得分:0)

见这个简单的例子,

function a(){
    this.someProp = 5;
    console.log(this);

    var _this = this;   //so we explicitly store the value of `this` to use in a nested function

    return function(){
        //value of `this` will change inside this function
        this.anotherProp = 6;
        console.log(this);

        //to use the methods and props of original function use `_this`
        console.log(_this)
    }
}

var c = a.call({})  //prints {someProp: 5}
c.call({})    //prints {anotherProps: 6} {someProp: 5}