JavaScript中this指向问题经典练习题加this规律

13 篇文章 0 订阅
7 篇文章 1 订阅

在这之前我们要先了解几条法则,了解以后对this的问题就会迎刃而解

  • 对象方法的内部函数的this指向window(非对象中的方法
  • 对象的方法内,this指向对象
  • 对象中的this指向window
  • 严格模式下(use strict)对象中禁止this关键字指向全局对象,此时的thisundefined如果此时出现this.a就会报错,因为undefined不能添加属性。
  • 如果说方法中的回调函数(就是方法return的值)是箭头函数,根据箭头函数的特点,他的this指向应该是根据上面的this指向来判断的。(简单的说就是上面的this指向什么下面的箭头函数就是指向什么的)。如果回调函数是一个普通的function函数那么始终是指向window的。
  • 如果把对象方法的函数赋值给全局变量的变量,此时再去调用这个变量的函数,这个时候变量是被window调用的。
  • 当函数1传入的是函数2的时候在函数2还在GO里面,此时函数2中的this是指向window

下面我们来举例子:
一:

			var obj = {
				a: 10,
				b: this.a + 10,  //this指向window  所以a为undefined
				fn: function() {
					return this.a; //this指向obj
				}
			}
			
			console.log(obj.b); //NaN
			console.log(obj.fn());

二:

			var a = 20;
			var obj = {
				a: 10,
				getA: function() {
					return this.a;
				}
			}
			
			console.log(obj.getA()); //10 对象obj调用方法,this指向obj对象
			var test = obj.getA; //表示将getA的属性值赋值给test变量,也就是将函数的地址赋值给test
			// var test = function(){
			// 	return this.a
			// }
			console.log(test()); //20 window调用方法,所以this指向window

这道题中我们需要注意的是,将函数赋值给了test此时再去调用test这个时候的test在全局变量中,所以此时testwindow调用。

三:

			var a = 5;
			
			// 顶层函数:this指向window
			function fn1() {
				var a = 6;
				console.log(a);  //6
				console.log(this.a); //谁调用方法,this就指向谁
			}
			
			function fn2(fn) { //fn = function fn1(){}
				var a = 7;
				fn(); //window调用的
			}
			
			var obj = {
				a: 8,
				getA: fn1
			}
			fn2(obj.getA);

当函数1传入的是函数2的时候在函数2还在GO里面,此时函数2中的this是指向window

四:

			function fn() {
				// "use strict";
				// 严格模式下:禁止this关键字指向全局对象
				// console.log(this); //undefined
				var a = 1;
				var obj = {
					a: 10,
					c: this.a + 20  //不能为undefined添加属性
				}
				return obj.c;
			}
			console.log(fn()); //Cannot read property 'a' of undefined

五:

			function Person(name, age) {
				this.name = name;
				this.age = age;
				console.log(this);//使用new创建出来的对象,输出Person
			}
			Person.prototype.getName = function() {
				console.log(this); //使用哪个对象来调用,this就指代谁,输出Person
			}
			var p1 = new Person("test", 18)
			p1.getName()

这里是给Person对象添加一个原型,还是在Person上面所以这个时候应该是指向Person

六:

			var obj = {
				foo: "test",
				fn: function() { //对象的方法内,this指向该对象
					var mine = this;
					console.log(this.foo); //"test" 
					console.log(mine.foo); //"test" 
					
					// 方法的内部函数的this指向window
					(function(){
						console.log(this.foo); //undefined
						console.log(mine.foo); //"test"  mine指向方法的局部变量mine,最终指向obj对象
					})()
				}
			}
			obj.fn();

在这里的考点其实是我们经常在项目中用到的,把上一层的this赋值给一个变量,然后再在下一层中使用这个变量,也就是下一层中使用的是上一层中的this.

七:

			function foo() {
				console.log(this.a);
			}
			
			var a = 2;
			var o = {
				a: 3,
				foo: foo
			}
			var p = {
				a: 4,
			}
			o.foo(); //3  对象调用方法,方法内的this指向该对象
			(p.foo = o.foo)(); //2  自调用函数  this指向window
			
			
			p.foo = o.foo;
			p.foo(); //4 对象调用方法,方法内的this指向该对象

在这里注意的是第二三个输出,第二个输出是自调用函数,this指向的是window也可以在这里把他看成将foo()这个函数赋值给p.foo这里的p.foo就是一个变量在window下面调用这个函数,现在的foo函数也是在window里面,而且又是一个自调用函数,所以此时是被window调用的。
第三个输出是先赋值然后再通过,p.foo()调用的,此时是被p调用的。

八:

        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

这里涉及到了一个方法劫持,顾名思义就是把一个对象劫持到另外一个对象上面比如obj1.foo.call(obj2)就是把objfoo方法劫持到了obj2上面现在的foo方法就是obj2调用的

九:

		<script type="text/javascript">
			function test(arg) {
				this.x = arg;
				console.log(this);
				return this;
			}
			var x = test(5);
			var y = test(6);
			
			console.log(window.x.x); //undefined
			console.log(y.x); //6

这道题的陷阱比较多,主要是全局变量中的x和函数中的this.x是一样的。这是一个陷阱。全局变量中的x y的返回值都是``window但是在执行x y的时候先进去的是5,此时window下面的x变成了5,然后又执行y此时的window下面的x变成了6。再来看看输出的结果,第一个相当于window.x.x这时候的window.x.x被上面赋值以后是6。6.x找不到,所以输出undefined
后面输出的是window.y.x这儿的window.y返回的是window就相当于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);
					return this.data.map(function(item) {
						console.log(this);
						return item*2;
					})
				},
				fn2: function() {
					console.log("-----test2-----");
					console.log(this);
					
					return this.data2.map(item => {
						console.log(this);
						return item*2;
					})
				}
			};
			obj.fn();
			obj.fn2();

这道题按照最开始的法则就可以得出结果了,我就不做过多的赘述了。

有错误希望各路大神指出。小弟感激不尽

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值