1.7 JS-this 史上最简单的this

this定义

this就是指针, 指向我们调用函数的对象; this是JavaScript中的一个关键字,它是函数运行时,在函数体内自动生成的一个对象,只能在函数体内部使用。

this规则

this 是很多人会混淆的概念,但是其实他一点都不难,你只需要记住几个规则就可以了。

  1. 全局环境中this指向全局变量(window)
  2. this一旦绑定,就不会被任何代码更改。
  3. 对this来说,new的优先级是最高的,如果let c=new foo(),那么foo()里的this就都会绑定在c上。
  4. call、apply、bind改变this,优先级仅次于new。
  5. 箭头函数的this取决于它外面第一个不是箭头函数的函数的this。
  6. 函数中的this,由调用函数的方式来决定(1)如果函数是独立调用的,在严格模式下(use strict)是指向undefined的,在非严格模式下,指向window(2)如果这个函数是被某一个对象调用,那么this指向被调用的对象;

this经典题


/*-----------题目一-------------------*/
           var obj = {   
                 a: 10,
                 b: this.a + 10, //这里的this指向window(规则1),a为undefined 
                 fn: function () {
                     return this.a;
                   }
             }
            console.log(obj.b);        //NaN(规则1)
            console.log(
                obj.fn(),         //10(规则6(2))
                obj.fn          
                //fn (干扰项,未加()的函数相当于一个变量,函数只有加()才会运行,返回对应的返回值)
            ); 

复制代码
/**-------------题目二 ----------------*/
            var a = 20; 
            var obj = {
                a: 10,
                getA: function () {
                    return this.a;
                  }
            }
            console.log(obj.getA());    //10
            var test = obj.getA; // test的值为:function (){ return this.a;}
            console.log(test());   // 20 
            // 调用test(),相当于调用function (){ return this.a;},
            // 相当于独立调用function (){ return this.a;}(规则6(1))
复制代码
/*-----------题目三-------------------*/ 
             var a = 5;
             function fn1(){
                 var a = 6;
                 console.log(a);        //6
                 console.log(this.a);   //5
             }  
             function fn2(fn) {
                 var a = 7;
                 fn();
            } 
             var obj = {
                 a: 8,
                 getA: fn1 // 注意,fn1不加()相当于变量赋值
    // 相当于:getA: function() {var a = 6; console.log(a);        //6 console.log(this.a);   //5}  
             }  
            fn2(obj.getA); // 6  5 //注意,此时obj.getA也没加(),也相当于变量赋值,
  //相当于: fn2(function() {var a = 6; console.log(a);        //6 console.log(this.a);   //5}  
  // 所以函数还是相当于独立调用,输出6 5。 (规则6(1))
复制代码
/*-----------题目四-------------------*/ 
               function fn( ) {
               'use strict';
                var a = 1;
                var obj = {
                    a: 10,
                    c: this.a + 20        //严格模式下,a指向undefined嘛,undefined.a报错
                }
                return obj.c;
              }
             console.log(fn());       //输出报错==》 a undefined(规则6(1))
复制代码
/*-----------题目五-------------------*/ 
 
            // 声明一个构造函数 
             function Person(name, age) {
                this.name = name;
                this.age = age;
                console.log(this);      
            }   
            // Person();           //this 指向window
            Person.prototype.getName = function () {
                console.log(this);     
            }; 
            var p1 = new Person("test", 18);// Person {name: "test", age: 18}
            p1.getName();// Person {name: "test", age: 18}


复制代码
 var obj = {
               foo: "test",
               fn: function(){
                   var mine = this;
                   console.log(this.foo);       //test
                   console.log(mine.foo);       //test
                   
                   (function(){
                   console.log(this.foo);    //undefined 由于这个立即函数是独立调用的,所以this指向window(规则6(1))
                   console.log(mine.foo);    //test
                   })();  
               } 
            };
            obj.fn();
 


复制代码

/*  --------- 题目七 -----------  */ 
           function foo(){
                console.log(this.a);
            }
            var a = 2;
            var o = {
                a:3, 
                foo: foo
            };
            var p = { a:4 };
            o.foo();  //3
            (p.foo = o.foo)();      //2  注意没加()就是变量赋值,立即执行函数独立调用,所以this指向window(规则6(1))
            p.foo = o.foo;
            p.foo();    //4     函数由p执行,p调用指向p(规则6(2))

复制代码
 /*  --------- 题目八 -----------  */ 
            function foo() {
                console.log(this.a);
            }
            var obj1 = {
                a: 3,
                foo: foo
            };    
            var obj2 = {
                a: 5,
                foo: foo
            };
            obj1.foo();     //3(规则6(2)
            obj2.foo();     //5(规则6(2)
            
            obj1.foo.call(obj2);    //5(规则4)
            obj2.foo.call(obj1);    //3(规则4)
 
复制代码
/*  --------- 题目九 有意思的一题-----------  */ 
 
          function test(arg) {
                this.x = arg;
                return this;
            } 
            /**
               var x = test(5);  -->  window.x = window.test(5);
            
            */
            var x = test(5);     //此时x = window 后面的x(window)覆盖了前面的x(5)
            var y = test(6);     //此时 x = 6,  y = window , 后面的x(6)覆盖了前面的x(window)
            console.log(x.x);     //undefined,   实际上是6.x  是undefined(规则6(2))
            console.log(y.x);     //6     实际上是window.x 也就是6 (规则6(2))


复制代码

/*  --------- 题目十 -----------  */ 
              var obj = {
                data: [1,2,3,4,5],
                data2: [1,2,3,4,5],
                fn: function () {
                   console.log("--test--");
                   console.log(this);   //{data: Array(5), data2: Array(5), fn: ƒ, fn2: ƒ}
                   return this.data.map(function (item) {
                         console.log(this);     //  -->  window (独立调用(规则6(1)))
                         return item * 2;
                    }); 
                },
                fn2: function () {
                   console.log("---test2---");
                   console.log(this);   //{data: Array(5), data2: Array(5), fn: ƒ, fn2: ƒ}
                   return this.data2.map(item=>{
                       console.log(this);   //  --> obj {data: Array(5), data2: Array(5), fn: ƒ, fn2: ƒ} 箭头函数(规则5)
                       return item * 2; 
                   });
                }
             };  
             obj.fn();
             obj.fn2();
 

复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享