bind()的语法问题很奇怪

时间:2016-01-07 11:10:09

标签: javascript

为什么在这个例子中myFunction1会抛出语法错误而myFunction2运行良好?他们不应该一样吗?

(function(){
  function MyClass(){
    this.val = "myVal";
    this.myFunction1();
    this.myFunction2();
  }

  MyClass.prototype.myFunction1 = function(){
    function otherFn() {
      console.log(this.val);
    }.bind(this);
    otherFn();
  }

  MyClass.prototype.myFunction2 = function(){
    var otherFn= function() {
      console.log(this.val);
    }.bind(this);
    otherFn();
  }

  var ins = new MyClass();
 })();

3 个答案:

答案 0 :(得分:3)

这里的区别在于函数声明函数表达式之间的区别。

您的function1使用函数声明

MyClass.prototype.myFunction1 = function(){
  function otherFn() {
    console.log(this.val);
  }.bind(this);
  otherFn();
}

函数声明不是表达式,并且在逐步执行代码时不会发生。在进入范围后,它们首先完成。

由于它们不是表达式,因此它们没有值,因此.bind无法处理。

您的第二个示例使用函数表达式

MyClass.prototype.myFunction2 = function(){
  var otherFn= function() {
    console.log(this.val);
  }.bind(this);
  otherFn();
}

由于这是表达式,因此在逐步执行代码时会对其进行评估,并且具有结果值,.bind可以对其进行操作。

所以为什么是第一个声明?纯粹是因为JavaScript的解析规则是如何定义的。如果在期望语句时遇到function,则会启动函数声明。如果在遇到表达式的情况下遇到function,则会启动函数表达式。

function1中,function出现在需要声明的地方,因此是声明。但是,在function2中,它出现在var otherFn=之后,因此只能是表达式。

(*“其中需要一个语句”在JavaScript中,任何表达式[函数表达式除外]都允许在需要语句的地方,它被称为 ExpressionStatement。所以它结束是“预期语句或非函数表达式的位置。但反过来却不正确,当表达式被预期时,语句无效。”

答案 1 :(得分:0)

function otherFn() {
    console.log(this.val);
}.bind(this);

不正确。

只是在第一次运行第一个函数时,代码会中断,然后停止执行。所以你永远不会完成你的第二个功能。

尝试

var otherFn = function() {
    console.log(this.val);
}
otherFn.call(this);

代替。

答案 2 :(得分:0)

这是因为javascript解析你的code.otherFn在Function1中是一个parseTime函数,所以我们当时不能绑定上下文。其中Function2中的otherFn是运行时函数,因此我们可以绑定上下文。因此,如果要在Function1中调用otherFn,请使用以下语法。

在Function1的otherFn中的

otherFn.call(this),它将在运行时绑定上下文。