JS 正确判断this指向,理解call/apply使用

this对象是在运行时,基于函数的执行环境绑定的。指向大致分为四种:
1)对象的方法调用,this = 该对象;
2)普通函数,this  = window;
3)构造器;
4)Function.prototype.call/apply

1、作为对象的方法调用

	var a = 2
	var obj = {
		a: 1,
		getValue: function(){
			console.log(this.a)
		},
		// 箭头函数 改变this指向 this = window
		getArrowValue: () => {
			console.log(this.a)
		}
	}
	// getValue方法是作为obj对象的属性被调用的,this = obj
	obj.getValue() // 1
	obj.getArrowValue() // 2
	// 属于普通函数调用,this = window
	var f1 = obj.getValue
	f1() // 2

如果对象中的方法返回一个匿名函数,涉及到闭包,情况就不一样了。

	var a = 2
	var obj = {
		a: 1,
		getValue: function(){
			return function(){
				console.log(this.a)
			}
		}
	}
	obj.getValue()() // 2
函数被调用时,会创建一个执行环境和相应的作用域链,得到两个变量:this、arguments。
内部函数在搜索这两个变量时,只会搜索到其活动对象为止。

解决这类问题,可以在匿名函数外定义一个变量,把this传给变量,

getValue: function(){
			const self = this
			return function(){
				console.log(self.a)
			}
		}

2、普通函数调用

上述 var f1 = obj.getValue;f1() 属于普通函数调用,this是指向全局对象的。

3、构造器调用

JS没有类,但是可以从构造器中创建对象,使用new运算符,返回对象,通常情况,构造器里的this是
指向返回的这个对象的。

但是,如果构造器显示的返回一个object类型的对象,返回结果会是该对象;

	const MyClass = function() {
		this.name = 'qwe';
		return {
			name: 'asd'
		}
	}
	const obj = new MyClass()
	console.log(obj.name) // asd

4、Function.prototype.call/apply调用

在一个对象的上下文中应用另一个对象的方法;
作用一样,都是动态的改变this的执行,并立即执行函数。是传入参数的形式不同,第一个参数都是指定函数体内this对象的指向。
(A对象调用B对象的方法)
 call是列表:B.call(A, args1,args2)
 apply是数组:B.apply(A, arguments)
	let obj1 = {
		name: 'qwe',
		getName: function() {
			return this.name
		}
	}
	const obj2 = {
		name: 'asd'
	}
	console.log(obj1.getName()) // qwe
	// this指向obj2
	console.log(obj1.getName.call(obj2)) // asd

A.apply(null,[1,2,3]) 第一个参数传null,非严格模式下,函数体内的this会指向全局对象(node:global,浏览器:window)

this.name = 'zxc'
	let obj1 = {
		name: 'qwe',
		getName: function() {
			return this.name
		}
	}
	console.log(obj1.getName()) // qwe
	console.log(obj1.getName.call(null)) // zxc

在这补充一下call和apply的用途

5、箭头函数this指向

箭头函数的this是在定义函数时绑定的,不是在执行过程中绑定的。

简单的说,函数在定义时,this就继承了定义函数的对象。

eg1:

在事件函数里,有一个内部函数func,在事件函数内部调用func,func体内的this会指向window,而不是我们想要的事件函数的this
(ps:参考了JS设计模式和小红书)

你可能感兴趣的:(javascript)