JavaScript 关于关键字this指向的面试题

this指向

this是指包含它的函数作为方法被调用 时所属的对象。(谁调用了我,我就是谁的对象,谁最后调用了我,我就是谁的对象。)
注意:一定是this所在的函数作为方法被调用,才有可能改变this指向,也就是说这个this外面有个函数,被调用了!

  • 箭头函数没有自己的this, 它会捕获其所在(即定义的位置)上下文的this值, 作为自己的this值
  • 匿名函数的this指向所在的方法被调用的那个对象
  • 作用域对象—看例1

1、第一个比较牛逼啦

 let length = 10;
    function fn(){
        console.log(this.length);
    }
    let obj = {
        length:5,
        method: function(fn){
	    fn();
	    arguments[0]();
        }
    }
    obj.method(fn,1);
正确答案:
0
2
谷歌浏览器测试

解析:

首先,使用let关键字定义变量, 在规范中要求,不允许重复定义。 在传统的JS习惯中,所有var直接定义的变量,均为window对象的属性。
即window充当了全局作用域对象 那么,如果window中已经存在一个length属性,重复定义length应该是不被允许的。
由于规范中没有对这种情况做明确的规定。
IE浏览器和谷歌浏览器测试结果不一样

其次,这道题目重点考察的依然是this指向。 代码开始于 obj.method(fn,1); 然后进入到method方法中 直接调用了
fn(); fn作为method方法的参数,是一个局部变量,这种调用方式 既不等于obj.fn() ,也不等于window.fn()
等价于 scope.fn(); ,也就是作用域对象的调用

又因为,this不能打印作用域对象,这时只能显示window 那么第一次fn的执行,打印出的this.length,
就是window.length

结果为0

然后,是arguments0 这句代码 arguments是一个数组,里面存储了所有的参数。
在本例中,method方法被调用时,传入了两个参数,一个是fn,一个是数字1 因此,arguments[0]即代表fn
又因为,数组是特殊的对象,下标即是特殊的属性名

那么arguments0其实等价于: arguments.0();
最终,this.length,就等于arguments.length

结果为2

2、函数返回了一个函数表达式形式的声明,而这个调用的调用是在全局环境中,所以其内部的this就是指向window变量对象

  var name = "The Window";      
             var object = {
                 name : "My Object",              
                 getNameFunc : function(){
                     return function(){
                         return this.name;
                     };
                 }
             };
              
             alert(object.getNameFunc()());  //"The Window"
   // object.getNameFunc()返回了一个匿名函数,然后调用执行这个匿名函数。
    //因为这个匿名函数不是作为某个对象的方法来调用执行,所以它的this就是window对象

3、对象和箭头函数中的this

var btn = {
			name: "点我",
			click: function() {
				setTimeout(() => {
					console.log(this)
				}, 1000);
			},
			show: () => {
				console.log(this);
			},
			hide: function() {
				return () => {
					console.log(this)
				}
			}
		}


		btn.show(); //window   由于箭头函数没有this,且外面没有函数包着,就是指向默认的window对象
		btn.hide()(); //btn   btn.hide()返回的是箭头函数,**外面有hide方法包着箭头函数,箭头函数this指的是调用hide方法的那个对象**
		let temp = btn.hide(); 
		temp(); //btn   同理2
		let bb = btn.hide
		bb()(); //window  把hide函数给了全局变量bb
		btn.click(); //btn  箭头函数所在父级click方法的上下文是btn,因此this指向btn

4、

        var x = 11;
		var obj = {
			x: 22,
			y:function(){
				console.log(this);
			},
			z:()=>{
				console.log(this);
			}
			methods: {
				x: 33,
				say: function() {
					console.log(this.x)
				},
				say2: () => {
					console.log(this.x)
				}
			}
		}

		obj.methods.say(); //methods 33
		obj.methods.say2(); //window 11
        obj.y();  //  obj
		obj.z();  //window

5、定时器与箭头函数(改变this指向方法之一)

    var age = 99;
	function PersonX() {
		this.age = 0;
		setTimeout(() => {
			this.age++;
			console.log(age);
		}, 1000);
	}
	
	PersonX(); //1    
	//其实这里的this就是window,本是一个构造函数,但没有实例化对象; 进入PersonX内,全局变量内的age被修改为0,然后一秒之后+1,定时器内是个箭头函数,因此 this.age 的this和定时器内的this都是指的当前作用域对象,因此输出为1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值