总结js的this面试题

一、 this 的概念

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

 

1.   全局环境中this指向全局变量(window);

2.   函数中的this,由调用函数的方式来决定,

   (1)如果函数是独立调用的,在严格模式下(use strict)是指向undefined的,在非严格模式下,指向window;

   (2)如果这个函数是被某一个对象调用,那么this指向被调用的对象;

3.   构造函数与原型里面的this

     构造函数里的this以及原型里的this对象指的都是生成的实例;(由new决定的)

通过new操作符可以初始化一个constructor的指向,new的作用就是创建一个对象的实例,constructor也就指向了一个新的执行环境“在这个对象之中”;

4.  箭头函数按词法作用域来绑定它的上下文,所以this 实际上会引用到原来的上下文。

(箭头函数会保持它当前执行上下文的词法作用域不变,而普通函数则不会,箭头函数从包含它的词法作用域中继承了this的值)。

 

二、例题

/*-----------题目一-------------------*/
           var obj = {   
                 a: 10,
                 b: this.a + 10, //这里的this指向window(全局),a为undefined  ==>  undefined + 20 = NaN
                 fn: function () {
                     return this.a;
                   }
             }
            console.log(obj.b);        //NaN
            console.log(
                obj.fn(),         //10
                obj.fn            //fn
            );     
/**-------------题目二 ----------------*/
            var a = 20; 
            var obj = {
                a: 10,
                getA: function () {
                    return this.a;
                  }
            }
            console.log(obj.getA());    //10
            var test = obj.getA;
            console.log(test());        //20   独立调用test
 
/*-----------题目三-------------------*/ 
             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
             }  
            fn2(obj.getA); 
/*-----------题目四-------------------*/ 
               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

 

/*-----------题目五-------------------*/ 
 
            // 声明一个构造函数 
             function Person(name, age) {
                this.name = name;
                this.age = age;
                console.log(this);      //与下面的this是一样的,都是Person
            }   
            // Person();           //this 指向window
            Person.prototype.getName = function () {
                console.log(this);      //与上面的this是一样,都是Person
            }; 
            var p1 = new Person("test", 18);
            p1.getName();
/*--------- 题目六 -----*/ 
             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
                      console.log(mine.foo);    //test
                   })();  
               } 
            };
            obj.fn();

              /**
                (1) 在外部函数中, this 和 mine两者都指向了obj,因此两者都可以正确地引用访问foo;
               (2) 在内部函数中,  this不再指向obj, this.foo 没有在内部函数中被定义,
                 而指向到本地的变量mine保持在范围内,并且可以访问(在ES5之前,内部函数的this将指向全局的
                 window对象; 则作为ES5,内部函数中的this是未定义的。)
            
            */
/*  --------- 题目七 -----------  */ 
           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
            /**
                相当于: 
                function w(){
                    p.foo = o.foo;
                }
                w();
                此时的constructor指向window,调用这个w,这个w是在window下创建的,相当于
                调用window.w(),所以constructor指向window。
            */

            p.foo = o.foo;
            p.foo();    //4     函数由p执行,那么constructor指向的就是对象p,谁调用就指向谁0.0
            //this也就指向p, 因此this.a === p.a
 /*  --------- 题目八 -----------  */ 
 //明确绑定的优先权要高于 隐含绑定
            function foo() {
                console.log(this.a);
            }
            var obj1 = {
                a: 3,
                foo: foo
            };    
            var obj2 = {
                a: 5,
                foo: foo
            };
            obj1.foo();     //3
            obj2.foo();     //5
            
            obj1.foo.call(obj2);    //5
            obj2.foo.call(obj1);    //3

            // new 绑定的优先级高于隐含绑定,并且new 和call/ apply不能同时使用,所以
            // new foo.call(obj1)是不允许的,也就是不能直接对比测试 new绑定 和 明确绑定
/*  --------- 题目九 有意思的一题-----------  */ 

          function test(arg) {
                this.x = arg;
                return this;
            } 
            /**
               var x = test(5);  -->  window.x = window.test(5);
            
            */
            var x = test(5);     //此时 x = window, y = undefined
            var y = test(6);     //此时 x = 6,  y = window , 后面申请的x会覆盖掉第一次在this.x 生成的window.x
            console.log(x.x);     //undefined,   实际上是6.x  是undefined
            console.log(y.x);     //6     实际上是window.x 也就是6
/*  --------- 题目十 -----------  */ 
              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
                         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: ƒ}
                       return item * 2; 
                   });
                }
             };  
             obj.fn();
             obj.fn2();

 

 

  • 8
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值