书说---this

This是什么

  A书:一种机制,提供优雅的方式隐式传递对象的引用。

  B书:this总是指向一个对象

  C书:this是调用上下文(即对象)

    this是传递对象的引用,各书只是用不同方式去表达出来

This的绑定

  A书:与函数的声明和位置无关,取决于函数的调用方式

  B书:不是在函数声明时的环境,是动态绑定的--在运行时基于函数的执行环境​

  C书:函数的四种调用机制的不同,就能判断每种调用类型的this

    this的指向:不是根据词法作用域,是根据函数的调用方式,才决定指向谁!

 清楚函数的调用方式,你还会被this骗吗

  作为对象的方法调用

1 //当函数作为对象的方法被调用时,this 指向该对象:
2 var obj = {
3     a: 1,
4      getA: function(){
5       alert ( this === obj ); // 输出:true
6         alert ( this.a ); // 输出: 1
7      }
8 };
9 obj.getA();
this指向对象

  作为函数调用

1  window.name = 'globalName';
2       var getName = function(){
3         return this.name;
4       };
5   console.log( getName() ); // 输出:globalName
this指向顶级对象

  顶级对象默认是window,严格模式默认undefined。(我理解:所以函数调用可以理解作为为window对象的方法调用)

  作为构造器调用

1 //构造器调用
2     var MyClass = function(){
3          this.name = 'sven';
4     };
5     
6      var obj = new MyClass();
7       alert ( obj.name ); // 输出:sven
this指向构造的新对象

  call和apply调用

 1    //方法的借用,apply/call方法接收第一个参数就是this的指向 
 2     var obj1 = {
 3        name: 'sven',
 4        getName: function(){
 5              return this.name;
 6                 }
 7     };
 8     var obj2 = {
 9           name: 'anne'
10      };
11     console.log( obj1.getName() ); // 输出: sven
12     console.log( obj1.getName.call( obj2 ) ); // 输出:anne
this指向你决定的对象

绑定的规则

 显式绑定:函数new、call和apply的调用

 隐式绑定:作为对象方法调用,作为函数调用

 A书:优先级---new > call/apply > 对象方法 > 普通函数

  call/apply > 对象方法

 1     function foo() {
 2        console.log( this.a );
 3     }
 4     var obj1 = {
 5       a: 2,
 6       foo: foo
 7     };
 8     var obj2 = {
 9       a: 3,
10       foo: foo
11     };
12      obj1.foo(); // 2
13      obj2.foo(); // 3
14      obj1.foo.call( obj2 ); // 3
15      obj2.foo.call( obj1 ); // 2
显式比隐式的优先级高

总结:看函数的调用,才是this指向的关键

           在隐式下,调用方法属于那个对象,this就指向那个对象

this的”丢失“

    经常被this搞混乱是:函数作为对象调用还是作为函数调用

因为​在属性的调用、变量的赋值间切换,由原来的对象调用--函数调用

对象间的切换

     对象属性引用链(多个对象调用):this指向上一级

 1 function foo() {
 2          console.log( this.a );
 3       }
 4       var obj2 = {
 5          a: 42,
 6          foo: foo
 7       };
 8       var obj1 = {
 9            a: 2,
10            obj2: obj2
11       };
12        obj1.obj2.foo(); //42
View Code

   赋值的是目标函数的引用:默认绑定顶级对象

1     function foo() {
2         console.log( this.a );
3     }
4     var a = 2;
5     var o = { a: 3, foo: foo };
6     var p = { a: 4 };
7       o.foo(); // 3
8      (p.foo = o.foo)(); // 2  
9  //赋值表达式p.foo = o.foo 的返回值是目标函数的引用,换句话就是调用foo()
我也不是很懂

      你只是知道this,不代表你this都做得对。当this与其他一起使用,就不只有this的规则还有其他规则

 

注意:纸上得来终觉浅,终知此事要躬行

  只有实践过的知识才最深刻。

ABC书:《你不知道的js》上、《js设计模式与开发实践》、《js忍者秘籍》  

原文地址:https://www.cnblogs.com/TAO-JL/p/9490550.html