JS高级 之 彻底搞懂this指向

JS高级 之 彻底搞懂this指向_第1张图片

目录

一、为什么使用this

1. 不使用this

2. 使用this

二、this的绑定规则

1. 栗子

2. 绑定方式一 : 默认绑定

01 - 栗子壹 : 普通函数调用

02 - 栗子贰 : 函数中调用另一个函数

03 - 栗子叁 : 函数作为参数调用

04 - 栗子肆 : 函数被赋值调用

05 - 小结

3. 绑定方式二 : 隐式绑定

01 - 栗子壹 : 对象调用函数

02 - 栗子壹 : 对象调用函数 ( 进阶 )

4. 绑定方式三 : 显式绑定

call 和 apply

        栗子

bind 

        01 - 栗子壹 : bind绑定this

        02 - 栗子贰 : bind绑定this并传入参数

        03 - 栗子叁 : bind后再使用call或apply指定this

5. 绑定方式四 : new绑定

栗子

三、this的规则优先级

1. 默认规则的优先级最低

2. 隐式绑定优先级高于默认绑定

3. 显示绑定优先级高于隐式绑定

01 - 栗子壹 : apply 和 call 高于隐式绑定

02 - 栗子贰 : bind高于隐式绑定

03 - 栗子叁 : bind的优先级高于apply、call 

4. new绑定优先级高于bind绑定

01 - 栗子壹 : new 高于隐式绑定

02 - 栗子贰 : new 不能和call、apply一起使用

03 - 栗子贰 : new 高于 bind 绑定

5. 总结一下

四、箭头函数中的this

1. 栗子一 

2. 栗子二

3. 栗子三

五、面试题

面试题一

面试题二

面试题三

面试题四

总结 : 注意箭头函数中没有this,注意连续点语法调用


一、为什么使用this

在某些函数或者方法的编写中,this可以让我们以更加优雅的方式来引用对象

1. 不使用this

const stu = {
  name: 'star',
  age: 18,
  eat() {
    console.log(stu.name + 'eating');
  },
  run() {
    console.log(stu.name + 'runing');
  }
};

那么在对象中定义的方法,需要获取自身的属性时,需要通过对象名来调用

一旦对象改了名字,函数中的名称也需要随之改变 

2. 使用this

const newStu = {
  name: 'star',
  age: 18,
  eat() {
    console.log(this.name + 'eating');
  },
  run() {
    console.log(this.name + 'runing');
  }
};

当通过对象去调用对应的方法时,而且不论对象名称怎么改变,方法中的this就指向该对象,可以让代码变得更加优雅些 


二、this的绑定规则

1. 栗子

同一个函数,不同的调用方式,函数中的this的指向都不一样

所以可以得出 : 

  1. 1.函数在调用时,JavaScript会默认给this绑定一个值
  2. 2.this的绑定和定义的位置(编写的位置)没有关系
  3. 3.this的绑定和调用方式以及调用的位置 有关系
  4. 4.this是在运行时被绑定

2. 绑定方式一 : 默认绑定

默认绑定 : 独立函数调用

  • 函数被直接调用,并没有进行任何的对象关联
  • 通常默认绑定时,在非严格模式下,this指向window,严格模式下,this指向undefined

01 - 栗子壹 : 普通函数调用

02 - 栗子贰 : 函数中调用另一个函数

03 - 栗子叁 : 函数作为参数调用

04 - 栗子肆 : 函数被赋值调用

05 - 小结

在真正函数调用的位置,都是直接调用该函数,所以都是指向window 

3. 绑定方式二 : 隐式绑定

隐式绑定 : 通过对象进行调用

01 - 栗子壹 : 对象调用函数

02 - 栗子壹 : 对象调用函数 ( 进阶 )

4. 绑定方式三 : 显式绑定

注 : 如果在显示绑定中,我们传入一个null或者undefined,那么这个显示绑定会被忽略,使用默认规则

call 和 apply

可以直接指定函数内部的this是谁,通过call和apply方法

call和apply : 

  • 第一个参数是相同的,要求传入一个对象
    • 这个对象就是给this准备的
    • 在调用这个函数时,会将this绑定到这个传入的对象上
  • 后面的参数,apply为数组,call为参数列表
    • func.apply ( thisArgs, [arg1, arg2, arg3] )
    • func.call ( thisArgs, arg1, arg2, arg3 )

        栗子

bind 

如果希望一个函数总是显示的绑定到一个对象上,使用bind方法

  • bind 方法创建一个新的绑定函数(bound function,BF)
  • 在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用

        01 - 栗子壹 : bind绑定this

        02 - 栗子贰 : bind绑定this并传入参数

        03 - 栗子叁 : bind后再使用call或apply指定this

bind的优先级高于call和apply

5. 绑定方式四 : new绑定

使用new关键字来调用函数是,会执行如下的操作:

  1. 创建一个全新的对象
  2. 这个新对象会被执行prototype连接,对象的proto会指向该构造函数的prototype
  3. 这个新对象会绑定到函数调用的this上(this的绑定在这个步骤完成)
  4. 运行函数内的代码
  5. 如果函数没有返回其他对象,表达式会返回这个新对象

栗子


三、this的规则优先级

1. 默认规则的优先级最低

默认规则的优先级是最低的,因为存在其他规则时,就会通过其他规则的方式来绑定this 

2. 隐式绑定优先级高于默认绑定

3. 显示绑定优先级高于隐式绑定

01 - 栗子壹 : apply 和 call 高于隐式绑定

02 - 栗子贰 : bind高于隐式绑定

03 - 栗子叁 : bind的优先级高于apply、call 

4. new绑定优先级高于bind绑定

  • new绑定和call、apply是不允许同时使用的,所以不存在谁的优先级更高
  • new绑定可以和bind一起使用,new绑定优先级更高

01 - 栗子壹 : new 高于隐式绑定

02 - 栗子贰 : new 不能和call、apply一起使用

03 - 栗子贰 : new 高于 bind 绑定

5. 总结一下

 new 优先级 > bind 优先级 > apply | call 优先级 > 隐式绑定  > 默认绑定


四、箭头函数中的this

箭头函数不使用this的四种标准规则(也就是不绑定this),而是根据外层作用域来决定this

1. 栗子一 

2. 栗子二

3. 栗子三


五、面试题

面试题一

面试题二

面试题三

面试题四

总结 : 注意箭头函数中没有this,注意连续点语法调用

你可能感兴趣的:(JS高级,javascript,前端,开发语言,this,前端,this)