js -> this

优先级: new绑定 > 显式绑定 > 隐式绑定 > 默认绑定

1、 默认绑定
    console.log('this', this); //输出 Window
    function sayHello() {
        // this指向全局对象(非严格模式下)
        console.log("line 16 ~ sayHello ~ sayHello",this, this.name, name)
    }
    sayHello() //输出 Window、Tom、Tom
    var name = 'Tom'
2、 隐式绑定(格式: xxx.fn() || a.b.c.xxx.fn() 那么,this指向xxx)
    function sayHello() {
        console.log("line 16 ~ sayHello ~ sayHello",this, this.name, name)
    }
    var name = 'Tom'
    var Person0 = {
        name: 'Jack',
        sayHello: sayHello
    }
    Person0.sayHello() //输出 Person0、Jack、Tom
    var Person1 = {
        name: 'Sam',
        sayHello: sayHello,
        friend: Person0
    }
    // 不管有多少层,在判断this的时候,我们只关注最后一层,所以绑定的为 Person0
    Person1.friend.sayHello() //输出 Person0、Jack、Tom
    Person1.sayHello() //输出 Person1、Sam、Tom
    // 需注意:这种就不是隐式绑定(`隐式绑定的丢失`)
    var say = Person1.sayHello;
    say() //输出 Window、Tom、Tom

    var Person2 = {
        name: 'Mike',
        sayHello: function(){
            setTimeout(function(){
                // setTimeout的回调函数中,this使用的是默认绑定,为全局对象
                console.log("line 43 ~ setTimeout ~ sayHello",this, this.name, name)
            })
        }
    }
    var Person3 = {
        name: 'Bill',
        sayHello: sayHello
    }
    Person2.sayHello(); //输出 Window、Tom、Tom
    // 下面👇🏻的区别:setTimeout(fn,delay)相当于是将Person3.sayHello赋值给了一个变量fn,最后执行了变量,`隐式绑定的丢失`。
    setTimeout(Person3.sayHello,100); //输出 Window、Tom、Tom
    setTimeout(function(){
        Person3.sayHello(); //输出 Person3、Bill、Tom
    },200);
3、 显式绑定(通过call,apply,bind的方式,显式的指定this所指向的对象)
     function sayHello() {
        console.log("line 16 ~ sayHello ~ sayHello",this, this.name, name)
    }
    var name = 'Tom'
    var Person0 = {
        name: 'Jack',
        sayHello: sayHello
    }
    var Person1 = {
        name: 'Sam',
        sayHello: sayHello,
        friend: Person0
    }
  // 如果我们将null或者是undefined作为this的绑定对象传入call、apply或者是bind,这些值在调用时会被忽略,实际应用的是默认绑定规则。
    var sayH = Person0.sayHello;
    sayH() //输出 Window、Tom、Tom
    // 强硬绑定到 Persion1、Persion3
    sayH.call(Person0) //输出 Person0、Jack、Tom
    sayH.call(Person1) //输出 Person1、Sam、Tom
    sayH.call(null) //输出 Window、Tom、Tom
    var sayHi = function(fn) {
        fn()
    }
    // call(Person1, Person1.sayHello)相当于Person1.sayHello已经被赋值给fn了,隐式绑定也就丢了
    sayHi.call(Person1, Person1.sayHello);//输出 Window、Tom、Tom
3、 new绑定
    function newSayHi(name){
       this.name = name;
    }
    var newSay = new newSayHi('Hello ~ Hi') 
    console.log("line 80 ~ newSayHi ~ newSay",this, newSay, newSay.name) //输出 Window、newSayHi、Hello ~ Hi
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一、第一部分 1.1值类型和引用类型 1.1.1 值类型都是变量,通过在栈中进行存储,值类型在内存中所占的空间小;...
    洛珎阅读 3,865评论 0 1
  • 1. javascript的typeof返回哪些数据类型. 答案:string,boolean,number,un...
    townof1997阅读 1,774评论 0 0
  • 我相信很多人会将 this 和作用域混淆在一起理解,其实它们完全是两回事。 例如 this.xxx 和 conso...
    越前君阅读 3,030评论 0 2
  • 值类型 (1)值类型赋值的时候不会相互影响 // 值类型let a = 100let b = aa = 200co...
    WEB前端含光阅读 1,774评论 0 0
  • 1. JS创建变量的5种方式?varletconstfunctionexport/import 2. var,le...
    Angel_6c4e阅读 4,294评论 0 13