this绑定/this指向

  1. 默认绑定 - window
  2. 隐式绑定 - context
  3. 显示绑定 - call、apply、bind
  4. new绑定 - 新对象
  5. 箭头函数绑定 - 下层作用域

1.默认绑定

function fn1() {    let a = 1;    let fn2 = function () {        console.log(this);        console.log(this.a);    }    fn2();    return fn2}var a = 2;fn1() //window 2fn1()() //window 2 window 2

无论函数在哪申明或调用,调用时函数前无对象,this最终都指向window

2.隐式绑定

function fn() {    console.log(this.name);}let obj1 = {    name: "boj1",    fn}let obj2 = {    name: "obj2",    obj1}obj2.obj1.fn() //obj1

函数调用前有对象时,this就近指向上下文对象

若未寻找到属性返回undefined,不会在obj2上找

隐式失落

  1. 参数传递
  2. 变量赋值

参数传递

let name = "window"function fn() {    console.log(this.name);}let obj1 = {    name: "obj1",    fn}let obj2 = {    name: "obj2",    obj1}function func(param) {    param()}func(obj2.obj1.fn) //window
fn作为参数在func中调用,this指向失落,默认指向window

变量赋值

let name = "window"function fn() {    console.log(this.name);}let obj1 = {    name: "obj1",    fn}let obj2 = {    name: "obj2",    obj1}let func = obj2.obj1.fnfunc();//window
将fn赋给func,func的调用this默认指向window

3.显示绑定

  1. bind
  2. call
  3. apply

bind

let name = "window"function fn() {    console.log(this.name);}let obj1 = {    name: "obj1",    fn}let obj2 = {    name: "obj2",    obj1}function func1(param) {    param()}func1(obj1.fn.bind(obj2)) //obj2let func2 = obj1.fn.bind(obj2)func2() //obj2
绑定:fn.bind(obj) 将fn绑定在obj上并返回一个函数,不论是参数传递还是变量赋值都不会呈现绑定失落的状况
参数:bind第一个参数为绑定的对象,前面的能够追加参数作为函数的实参,传递一个数组时不会主动解构
优先级:显示绑定>隐式绑定>默认绑定
硬绑定:绑定后不可应用bind、call、apply再从新绑定

call

let name = "window"function fn() {    let name = this.name    return function fn1() {        console.log(name, this.name);    }}let obj1 = {    name: "obj1",    fn}let obj2 = {    name: "obj2",    obj1}function func1(param) {    param()}func1(obj1.fn.call(obj2)) //obj2 windowlet func2 = obj1.fn.call(obj2)func2() //obj2 windowfunc2.call(obj1) //obj2 obj1
绑定:call绑定不同与bind的返回一个绑定的函数,而是立刻执行这个函数
参数:与bind雷同,this指向第一个参数,后续参数作为实参,数组不主动解构
软绑定:本次调用时为绑定,下次执行还须要再次绑定
闭包:在绑定时只绑定最外层作用域,父函数返回的函数在调用时为默认绑定,当对其绑定时,其this会被绑定,不影响外层作用域

apply

let arr = ["param1", "param2"]let name = "window"function fn(...arr) {    console.log(this.name, arr[0], arr[1]);}let obj1 = {    name: "obj1",    fn}let obj2 = {    name: "obj2",}obj1.fn.apply(obj2, arr)//obj2 param1 param2
绑定:apply与call雷同,会立刻执行被绑定的函数,同样也是软绑定
参数:第一个参数也是绑定的对象,前面与call不同,apply传递的数组会解构赋给函数的的形参

4.new绑定

function fn(name) {    this.name = name}let obj = new fn("obj")console.log(obj.name); //objconsole.log(new fn("new"));// {name:new}
用new去调用函数,会将该函数作为一个构造函数,把该函数的this指向一个新创建的对象,返回该对象

5.箭头函数

能够与call中的例子比照

let name = "window"function fn() {    let name = this.name    return () => {        console.log(name, this.name);    }}let obj1 = {    name: "obj1",}let obj2 = {    name: "obj2",}let func2 = fn.call(obj2)func2() // obj2 obj2func2.call(obj1) // obj2 obj2let func1 = fn.call(obj1)func1() //obj1 obj1
箭头函数没有本人的this,它会应用上一层作用域的this
对箭头函数的绑定是没有成果的,批改指向须要批改下层作用域的this