JavaScript:举例说明this的四种绑定规则和遇到箭头函数时的情况

170 阅读4分钟

默认绑定

1.一种无法应用其他规则的默认形式,函数直接调用,this将指向全局对象(window)。
2.但要注意,严格模式下,this会绑定到undefined,然而函数在严格模式下调用函数却不会影响默认绑定。

  1. 栗子:小明的朋友请了很多人吃酒席,酒席摆满了两层楼,也请了小明。酒席的每桌饭搭配都不同,每个人只能选一桌吃。但小明是个贪吃鬼,对着面前的饭菜说:“我想吃这桌,我想吃这桌……”但因为还没入席吃饭,这里的所有饭菜都没进入谁的肚子,所以他无论指哪桌饭菜,都还是主人的。
function board1() {
    console.log(this.say); //window
};
function board2() {
    let board3 = function () {
        console.log(this.say); //window
        board1();
    };
    console.log(this.say); //window
    board3();
};
var say = "我要吃这个"
board2()

我要吃这个
我要吃这个
我要吃这个

  1. 栗子:这时候小明的老婆觉得有点丢人,就对他说:“在这丢什么人呢,这些你都不准吃”。没想到小明脸皮挺厚,那我到楼上吃。
function board1() {
    "use strict";
    if(this === undefined){
        console.log("一楼不能吃")
    }
    board2()
};
function board2(){
    if(this === window){
        console.log("我去吃二楼")
    }
}
board1()

一楼不能吃
我去吃二楼

隐式绑定

1.函数引用的时候有上下文对象,就运用了隐式绑定的规则,this会绑定到这个上下文对象。
2.隐式绑定有些情况会丢失绑定,变成默认绑定。其中一种情况是对象内的方法赋给对象外的变量,这时候的this又回到了全局范围;另一种典型的情况是回调函数

  1. 栗子:终于开席可以吃东西了,小明找了小孩那桌坐下来吃。他现在可以真正吃到东西了。现在他吃到的菜属于粤菜。
var board = {
    name:'粤菜',
    foods:'烤乳猪、白切鸡、老火靓汤、白灼虾',
    eat:function(){
        console.log("我吃的是" + this.name)
        console.log('我吃了' + this.foods)
    }
}
board.eat();

我吃的是粤菜
我吃了烤乳猪、白切鸡、老火靓汤、白灼虾

  1. 栗子:但我们知道小明是贪吃鬼,虽然吃着这一桌,但又想着那一桌,他盯上了川菜那一桌。当然想归想,他还是吃不到的。
var board1 = {
    name:'粤菜',
    foods:'烤乳猪、白切鸡、老火靓汤、白灼虾',
    eat:function(){
        console.log("我吃的是" + this.name)
        console.log('我吃了' + this.foods)
    },
    want:function(){
        console.log(this)
    }
}
board1.eat();
var board2 = board1.want;
board2()

我吃的是粤菜
我吃了烤乳猪、白切鸡、老火靓汤、白灼虾
Window{...}

显示绑定(硬绑定)

1.我们可以通过apply、call、bind将函数中的this强制绑定到指定的对象上。这样我们就可以期望他绑定到哪儿就绑定到哪儿。

  1. 栗子:然而小明还是忍不住了,迅速在粤菜席吃了一些,就假装刚刚还没吃过,跑去川菜那桌。
var board1 = {
    name:'粤菜',
    eat:function(){
        console.log("我吃的是" + this.name)
    },
}
var board2 = {
    name:'川菜',
}
board1.eat.call(board2)
board1.eat.apply(board2)

我吃的是川菜
我吃的是川菜

构造函数绑定

1.构造函数 在JavaScript中其实并不存在所谓的“构造函数”,构造函数只是使用new操作符时被调用的普通函数,它们并不属于某个类,也不会实例化一个类;对这种函数实际上是“构造调用”。
使用new来调用函数,或者说发生构造函数调用时,会自动执行下面的操作。

  • 创建(或者说构造)一个全新的对象
  • 此对象会被执行[[Prototype]]连接。
  • 这个新对象会绑定到函数调用的this
  • 如果函数没有返回其他对象,那么new表达式中的函数会自动返回这个新对象。
  1. 栗子:小明跑过去的时候发现川菜席已经没位置了,只好又回去粤菜席。其他地方没位置了,这下他不会受到诱惑跑到其他席去了。
function board(name){
    this.name=name;
    this.eat = function(){
        console.log("我吃的是" + this.name)
    }
}
var name = "川菜"
var xiaoming = new board('粤菜')
xiaoming.eat();

我吃的是粤菜

遇到箭头函数时的情况

不想写了(# ̄~ ̄#)
其实是这个还不太熟悉╮(╯▽╰)╭
隐式绑定也还有一点没写完,以后再补


参考:

JavaScript深入之史上最全--5种this绑定全面解析