this绑定

82 阅读4分钟

this的概念一共可以分为五种场景:

  1. 默认绑定
  2. 隐式绑定
  3. 显式绑定
  4. new绑定
  5. 箭头函数绑定

1、this的默认绑定

在函数调用没有任何前缀的时候,就属于this默认绑定。

 function fn3() {
     console.log(this); //window
 };
 ​
 f3();

在这段代码中,函数调用没有任何前缀,没有指定任何对象,那么this指向全局对象window

注意:在严格模式下,默认绑定的this指向undefined,代码如下

 function fn1() {
     console.log(this); //window
 };
 function fn2() {
     "use strict"; //在严格模式
     console.log(this); //undefined
 };
 fn1(); 
 fn2();

上面这个例子是在fn2的本地执行上下文里面使用"use strict",如果说是fn2函数外面使用严格模式将函数包裹住,那么与使用在里面的效果是相同的。

this的隐式绑定

在函数被调用之前,如果前面存在调用它的对象,那么this就会隐式绑定到这个对象上。

 function fo() {
     console.log(this.name);
 };
 let obj = {
     name: 'henu_GM',
     fo: fo
 };
 obj.fo();

如果函数调用前存在多个对象,那么this指向距离自己调用最近的对象,采取就近原则

 function fo() { 
     console.log( this.a );
 }
 var a = 7;
 var obj1 = { 
    a: 4,
    fo: fo
 };
 var obj2 = { 
     a: 3,
     obj1: obj1
 };
 obj2.obj1.fo();  // 4

注意:在特定情况下会发生隐式绑定丢失的问题,其中最主要的两个问题

1、将含this的函数作为参数传递给了另一个函数,这里的this并没有与之前那个函数绑定,而是与调用之前那个函数的对象隐式绑定,所以这里this脱离了绑定对象,this指向window

2、对已经隐式绑定了的函数进行变量赋值,在用新的变量调用这个函数,也会造成this指向window

就这么说吧,把函数作为参数进行传递给其他函数或者对象,如果接收的是一个新的对象,那么这个函数的this就指向新的对象,如果接收的是函数一类的,那么就直接指向window

this的显式绑定

显式绑定不同于隐式,显式绑定是指我们通过callapply以及bind方法改变this的行为。

通俗来讲,callappply让函数从被调用变为主动选择自己的上下文,称为函数应用。

需要注意的是,无论是call还是apply,亦或是bind,如果选择的参数是undefined或者null那么this将指向全局变量。

all,apply,bind理解与使用

this的new绑定

JavaScript中的构造函数,它只是使用new调用的一个普通函数,而并不是一个类,最终返回的对象也不是一个实例。

那么new一个函数究竟发生了什么:

  1. 以构造器的prototype属性为原型,创建对象。
  2. this和调用参数传给构造器。
  3. 如果构造器没有手动返回对象,则返回第一步创建的对象。

则叫做,构造调用。

那么就可以这么理解,thisnew绑定无非是创建一个对象是要调用的一个函数,而这个要使用到的构造函数的this在调用的过程中指向发起这次构造的对象,这就是thisnew绑定了。

箭头函数的this绑定

箭头函数ES6新增的属性,箭头函数中没有this,箭头函数的this指向外层作用域中的this,外层作用域或者函数的this指向谁,箭头函数中的this就指向谁。

有一点要注意,this的绑定类似于bind的硬绑定(callapply失效),就是说,一旦箭头函数的this绑定成功,就无法被再次改变。如果必需要改变的话,我们可以直接改变箭头函数的外层作用域的this指向,也可以。

this五种绑定方法的优先级

显式绑定 > 隐式绑定 > 默认绑定

new绑定 > 隐式绑定 > 默认绑定

据说new绑定是优先于显示绑定的,我试了一下,发现new的使用和显示绑定完全不在一个场景,不能判断它俩的优先级。


文章转自:blog.csdn.net/qq_53087870…