js十种this指向例题汇总(搞定它们js中this指向应该问题不大)

var obj = {
	a: 10,
	b: this.a + 10,
	fn: function() {
		return this.a;
	}
}
console.log(obj.b);
console.log(obj.fn());

运行结果:
obj.b => NaN
obj.fn() => 10

在对象里,属性里的this指向window,在全局作用域没有定义a,但由于是对象.a相当于创建了a,只是没赋值,this.a为undefined,加上一个数值,故NaN方法里的this指向方法的调用者,这里就是obj对象本身,执行函数,故得到对象里的a值10
2.

var a = 20;
var obj = {
	a: 10,
	getA: function() {
		return this.a;
	}
}
console.log(obj.getA());
var test = obj.getA;
console.log(test());

运行结果:
obj.getA() => 10
test() => 20

第一个输出10不难理解,就是对象里的方法this指向它的调用者obj;var test = obj.getA;相当把对象里的getA方法函数体赋值给test,即var test = function(){return this.a;}此时this指向window对象,故输出20。
3.

var a = 5;
function fn1() {
	var a = 6;
	console.log(a);
	console.log(this.a);
}
function fn2(fn) {
	var a = 7;
	fn();
}
var obj = {
	a: 8,
	getA: fn1
}
fn2(obj.getA);

输出结果:
a => 6
this.a => 5
首先从fn2函数调用开始,这里有个实参obj.getA,指的是obj对象里getA方法,而getA方法是fn1,即相当于在fn2里传了fn1函数,由于作用域,a输出6,this这里指的是window对象,故this.a值为5
4.

function fn() {
	'use strict';
	var a = 1;
	var obj = {
		a: 10,
		c: this.a + 20
	}
	return obj.c;
}
console.log(fn());

输出结果:

fn() => 报错
这个函数体内部是在严格模式下运行的,在严格模式下,禁止this关键字指向全局对象,对象属性里的this指向全局对象window,故会报错。
5.

function Person(name,age) {
	this.name = name;
	this.age = age;
	console.log(this);
}
Person.prototype.getName = function() {
	console.log(this);
}
var p1 = new Person('test', 18);
p1.getName();

输出结果:

构造函数里的this、原型上getName方法里的this都是指向实例化对象,故结果都是Person这个构造函数
6.

var obj = {
	foo: "test",
	fn: function() {
		var mine = this;
		console.log(this.foo);
		console.log(mine.foo);
		(function() {
			console.log(this.foo);
			console.log(mine.foo);
		})();
	}
};
obj.fn();

输出结果:

第一组:test test
第二组:undefined test
对象的方法里this指向方法的调用者,故第一组都是打印obj本身的foo属性值,在第二组时,由于时自执行函数,函数体内this指向的是window对象,在全局作用域下没有foo属性,故undefined,由于前面把this赋值给了一个变量保存,所以第二组mine.foo还是调用对象的属性foo。
7.

function foo() {
	console.log(this.a);
}
var a = 2;
var o = {
	a: 3,
	foo: foo
};
var p = {
	a: 4
};
o.foo();
(p.foo = o.foo)();

p.foo = o.foo;
p.foo();

输出结果:

o.foo() => 3
(p.foo = o.foo)() => 2
p.foo() => 4
o.foo()指访问o对象里有个名为foo的方法,并执行它,这里我们知道了,这是对象内的方法,this指向o这个对象,故为3;第二个是个自执行函数,它是把对象o的方法foo添加到对象p的方法中去,但由于此时是个自执行函数,函数体内this指向window,故为2;第三个也是如同第二个,只不过是在是访问对象内的方法,此时this指向对象p,故为4.
8.

function foo() {
	console.log(this.a);
}
var obj1 = {
	a: 3,
	foo: foo
};
var obj2 = {
	a: 5,
	foo: foo
}; 
obj1.foo();
obj2.foo();

obj1.foo.call(obj2);
obj.foo.call(obj1);

输出结果:

obj1.foo() => 3
obj2.foo() => 5

obj1.foo.call(obj2) => 5
obj1.foo.call(obj1) => 3
这道题没什么说的,只不过利用call方法改变了函数内this指向,不清楚这个方法的可以看这篇博客:
https://blog.csdn.net/qq_48784569/article/details/107562945
9.

function test(arg) {
	this.x = arg;
	return this;
}
var x = test(5);
var y = test(6);
console.log(x.x);
console.log(y.x);

输出结果:

x.x => undefined
y.x => 6
这道题有点意思:首先我们分析我们把5这个实参传给了test函数的形参,函数体内this指向window,即在window下添加了一个x属性值为5,函数返回这个window对象通过全局变量x接受,但由于此时x也是window对象上的,执行x.x时它会覆盖之前window.x=5,现在是window.x=window,所以它不会向我们想的那样拿到5,而是无限循环访问window对象;而执行y = test(6)时,把6传进去,此时window对象上的x又一次被覆盖,现在是window.x=6,通过全局变量y去接受这个返回值window对象,相当于是window.y=window,即此时window.x=6了,y变为window对象了,可以通过y.x访问到6,用x.x访问时全局变量x变成了数值了,故是undefined
10.

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();

输出结果:
在这里插入图片描述
实际这里主要是让我们区分箭头函数普通函数的区别,这里是对象,在fn方法内this指向调用者,故为obj对象,在return语句里函数里由于window下调用了函数,故this指向window,循环输出5次window对象;在fn2方法里,同理,this指向obj对象,在箭头函数里,this指向靠近的作用域,故为obj对象。
这里扩展一下箭头函数和普通函数的区别吧:

  • 箭头函数体内this对象,是定义时所在的作用域中的this值,而不是使用时所在的对象;
  • 不可以使用arguments对象,该对象在函数体内不存在,如果要用,可以用rest参数(剩余参数)代替;
  • 不可使用yield命令,因此箭头函数不能做Generator函数
  • 不可使用new命令:因为没有自己的this,无法调用call()、apply();没有prototype属性,而new命令在执行时需将构造函数的prototype赋值给新对象__proto__。
  • 9
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值