bind()存在奇怪的语法问题

Strange syntax issue with bind()

本文关键字:语法 问题 存在 bind      更新时间:2023-09-26

为什么在这个例子中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();
 })();

这里的区别是函数声明功能表达式之间的区别。

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。因此,它最终会成为"需要语句或非函数表达式的地方"。但反之亦然,当需要表达式时,语句无效。)

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

不正确。

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

尝试

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

相反。

这是由于javascript解析代码的原因。Function1中的otherFn是一个parseTime函数,因此我们当时无法绑定上下文。函数2中的as otherFn是一个运行时函数,因此我们可以绑定上下文。因此,如果您想在Function1中调用otherFn,请使用以下语法。

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