开头
对于新手来说,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)
差不多就到这了,后期想到什么再补充吧,有什么不对的或者遗漏的请勿喷,好了,同学该你了!