JavaScript系列-this详解

155 阅读1分钟

Dome

打印对象name值

    // 一般方式
    var person = {
        name : "dengge"
    }
    function idetify(obj){
        return obj.name.toUpperCase();
    }
    console.log(idetify(person))


    // 优化方式
    var person = {
        name : "dengge"
    }
    //api 框架
    function idetify(){
        return this.name.toUpperCase();
    }
    console.log(idetify.call(person))

优化方式: 借用call()方法 修改this的指向

当前this指向被调用的对象 优化方式减少了:参数的传递 更易提供一个库调用

this 四个规则

this默认绑定

非严格模式 window 严格模式 undefined

 var id = 10;
 function fn(){
    console.log(this.id);
 }
 fn() // 10

fu() == window.fn() 所以当前this指向Window 所以: id -> window.id = 10

非严格模式 window 严格模式 undefined

隐式绑定

如果一个环境调用 走这个环境的this

  var id = 10;
  var obj = {
        id : 20,
        fn : function(){
            console.log(this.id)
        }
  }
  obj.fn(); // id = 20 (this指向obj)

  var fn2 = obj.fn;

  fn2(); // 10 (this指向window)

  function callback(fn){
    fn()
  } 
  callback(obj.fn) //10 (callback -> window, this指向window)

如果一个环境调用 走这个环境的this

明确绑定

  1. call apply 绑定丢失
     function fn() {
        console.log(this.id);
     }
     var obj1 = {
        id : 30
     }
     var obj2 = {
        id : 40
     }
     var obj3 = {
        id : 50
     }
     var obj4 = {
        id : 60
     }
     fn.call(obj1); // 30 (call使得this指向了obj1)
     fn.apply(obj2); // 40 (call使得this指向了obj2)
    
  2. 硬绑定(bind)
        var fun = fn.bind(obj3);
        fun.call(obj1);  // 50 (bind使得this指向了obj3 不会修改成obj1)
        fun(); // 50
    

new 绑定

// 构造函数
function person(){
    this.name = "dengge";
    return {
        a : 1
    };
}
var p = new person();
console.log(p.name) // "dengge" (new使得this指向了p对象)

ES6箭头函数this

function foo() {
  setTimeout(() => {
    console.log('id:', this.id);
  }, 100);
}

var id = 21;

foo.call({ id: 42 }); 
// id: 42 (如果没有setTimeout(fn(),100) this这时指向window  此时this指向了对象{id:42}  箭头函数没有自己的this,内部的this指向外部的this({id:42}))

箭头函数里的this是定义时所在的作用域, 而不是运行时所在的作用域 箭头函数没有自己的this,内部的this指向外部的this