Js中关键字this总结

267 阅读2分钟

开头

对于新手来说,js中变换莫测的this确实是一个很头疼的问题,笔者刚开始亦是如此,今天抽空就来总结一下this的指向问题(笔者水平有限就不讨论node中的this指向了,仅总结下浏览器中的this)

首先来个总结:函数中的this,由谁来触发,this就指向谁 这也是笔者最开始的理解,基本是没有问题的,下面就来分情况总结下。

全局环境

console.log(this)  // window  

全局指向undefined,但是非严格模式下undefined会自动指向window

函数自执行

function fn(){
    console.log(this)
}
fn()  // window,在严格模式下"use strict" undefined
window.fn()  // window

谁调用指向谁

事件处理函数

 <div id="box" onclick="console.log( this )" >div</div>  //box
 <div id="box" onclick="( (function(){console.log( this )})() )" >div</div>  //window
 <script>
    box.onclick = function(){
        console.log(this)  //box
    }
 </script> 

call、apply、bind

这三个方法都可以修改this的指向区别、应用、底层实现戳我

1、call方法 fn.call(this,1,2,3)

2、apply方法 fn.apply(this,[1,2,3])

3、bind方法 let fn1 = fn.bind(this,1,2,3)

call和apply 主要是参数的格式不同,会立即执行函数,而bind是会返回一个新的修改了this指向的函数

function fn(){
    console.log(this)
}
fn.call(1)  // Number{1}
fn.bind({a:1})()  // {a:1}

箭头函数

ES6中的箭头函数本身就没有this指向,this默认指向父级作用域中的this,所以也不存在call、apply、bind修改this指向的问题。

box.onclick = function(){
    setTimeout(function(){
        console.log(this)  // window
    },1000)
}
box.onclick = function(){
    setTimeout(()=>{
        console.log(this)  // box
    },1000)
}

箭头函数比较"直男",ES5中定义的函数比较"善变"

var a = 1
var obj = {
	a: 2,
	fn1: ()=>{
	    console.log( this.a )
	},
	fn2: function(){
	    console.log( this.a )
	}
}
obj.fn1()  // 1
obj.fn2()  // 2
var a = 1;
var obj = {
	a: 2,
	fn1: function(){
		return function(){
			console.log( this.a )
		}
	},
	fn2: function(){
		return ()=>{
			console.log( this.a )
		}
	},
	fn3: ()=>{
		return function(){
			console.log( this.a )
		}
	},
	fn4: ()=>{
		return ()=>{
			console.log( this.a )
		}
	}
}

var innerFn1 = obj.fn1();
innerFn1();  // 1

var innerFn2 = obj.fn2();
innerFn2();  // 2

var innerFn3 = obj.fn3();
innerFn3();  // 1

var innerFn4 = obj.fn4();
innerFn4();  // 1

对象中

var a = 1;
var obj = {
	a: 2,
	o: {
	    a: 3,
	    fn: function(){
	        console.log(this.a)
	    }
	}
};
obj.o.fn();  // 3
var temp = obj.o.fn;
temp();  // 1

构造函数中

function Person(){
    this.name = "zhangSan"
    this.age = 25;
}
var person = new Person()
console.log(person)

这里就提一下new运算符的流程:

1、创建一个空对象

2、把这个对象指向this

3、执行代码块

4、隐式返回this(没有return隐式返回this,return非 null 的对象,那么实例化结果就是返回这个对象,否则返回this)

差不多就到这了,后期想到什么再补充吧,有什么不对的或者遗漏的请勿喷,好了,同学该你了!