详解JS中的应用,电话,绑定(经典面试题)

  

这又是一个面试经典问题~/(ㄒoㄒ)/~ ~也是ES5中众多坑中的一个,在ES6中可能会极大避免这个产生的错误,但是为了一些老代码的维护,最好还是了解一下这个的指向和调用,应用,结合三者的区别。

  

  

在ES5中,其实这的指向,始终坚持一个原理:这个永远指向最后调用它的那个对象,来,跟着我朗读三遍:这永远指向最后调用它的那个对象,这永远指向最后调用它的那个对象,这永远指向最后调用它的那个对象。记住这句话,这你已经了解一半了。

  

下面我们来看一个最简单的例子:

  例1:

        var name=皐indowsName”;   函数(){   var name=坝L摇?   console.log (this.name);//windowsName   控制台。日志(“内部:" +);//内部:窗口   }   ();   控制台。日志(“外:“这+)//外:窗口      

这个相信大家都知道为什么日志的是windowsName,因为根据刚刚的那句话“这永远指向最后调用它的那个对象”,我们看最后调用一个的地方();,前面没有调用的对象那么就是全局对象窗口,这就相当于是window.a();注意,这里我们没有使用严格模式,如果使用严格模式的话,全局对象就是未定义的,那么就会报错未捕获TypeError:无法读取属性的名称定义。

  

再看下这个例子:

  例2:

        var name=皐indowsName”;   var={   名称:“樱桃”,   fn:函数(){   console.log (this.name);//樱桃   }   }    a.fn ();      

在这个例子中,函数fn是对象一个调用的,所以打印的值就是一个中的名称的值。是不是有一点清晰了呢~

  

我们做一个小小的改动:

  例3:

        var name=皐indowsName”;   var={   名称:“樱桃”,   fn:函数(){   console.log (this.name);//樱桃   }   }    window.a.fn ();      

这里打印樱桃的原因也是因为刚刚那句话“这永远指向最后调用它的那个对象”,最后调用它的对象仍然是对象。

  

我们再来看一下这个例子:

  例4:

        var name=皐indowsName”;   var={//名称:“樱桃”,   fn:函数(){   console.log (this.name);//定义   }   }    window.a.fn ();      

这里为什么会打印定义呢?这是因为正如刚刚所描述的那样,调用fn的是一个对象,也就是说fn的内部的这是对象,而对象一个中并没有对名字进行定义,所以日志的this.name的值是未定义的。

  

这个例子还是说明了:这永远指向最后调用它的那个对象,因为最后调用fn的对象是,所以就算一个中没有名字这个属性,也不会继续向上一个对象寻找this.name,而是直接输出定义。

  

再来看一个比较坑的例子:

  例5:

        var name=皐indowsName”;   var={   名称:空,//名称:“樱桃”,   fn:函数(){   console.log (this.name);//windowsName   }   }   var f=a.fn;   f (),      

这里你可能会有疑问,为什么不是樱桃,这是因为虽然将一个对象的fn方法赋值给变量了,但是没有调用,再接着跟我念这一句话:“这永远指向最后调用它的那个对象”,由于刚刚的f并没有调用,所以fn()最后仍然是被调窗用的,所以这指向的也就是窗口。

  

由以上五个例子我们可以看的出,这的指向并不是在创建的时候就可以确定的,在es5中,永远是这永远指向最后调用它的那个对象。

  

再来看一个例子:

  例6:

        var name=皐indowsName”;   函数fn () {   var=坝L摇泵?   innerFunction ();   函数innerFunction () {   console.log (this.name);//windowsName   }   }   fn ()      

读到现在了应该能够理解这是为什么了吧(o # 65439;▽& # 65439;) o。

  

  

改变这样的指向我总结有以下几种方法:

  

<强>使用ES6的箭头函数

  

在函数内部使用_this=这

  

<强>使用,电话,结合

  

新实例化一个对象

  例7:

        var name=皐indowsName”;   var={   名称:“樱桃”,   func1:函数(){   console.log (this.name)   },   func2:函数(){   setTimeout(函数(){   this.func1 ()   },100);   }   };//这个a.func2 ()。func1不是一个函数

详解JS中的应用,电话,绑定(经典面试题)