在我感觉里,js 中this 的指向问题相比其他语言有点迷,所以就整理总结下~
1.严格模式下,函数里的this 指向 undefined
'use strict'
this.a= 'aaa';//给全局this赋值
console.log("全局this:"+JSON.stringify(this));//全局this:{"a":"aaa"}
function func1(){
console.log('this='+this);
}
func1()//undefined
2.对象里的this 指向的是当前对象(无论函数是在对象里定义的还是外面定义)
'use strict'
this.a= 'aaa';//给全局this赋值
console.log("全局this:"+JSON.stringify(this));;//全局this:{"a":"aaa"}
var b ={
key:2
}
function func1(){
console.log('this='+this);
}
func1()//返回this=undefined,直接调用就是undefined
b.func1= func1;
b.func1();//返回 this={"key":2},将函数添加到对象上指向对象
function ObjectA(a,b){
this.a = a;
this.b = b;
}
var objectA1= new ObjectA(1,2)//通过构造器new 的对象
objectA1.func1 = func1;
objectA1.func1();//this={"a":1,"b":2} ,this 指向 objectA1 对象
3.es6中 箭头函数 this 的指向问题
箭头函数的this 指向的上一层的对象,若没有再上一层对象,则指向全局window/global
'use strict'
this.a= 'aaa';//给全局this赋值
console.log("全局this:"+JSON.stringify(this));;//全局this:{"a":"aaa"}
var func2 =()=>{
console.log('this='+JSON.stringify(this));
}
var b ={
key:2,
func3:()=>{
console.log('this='+JSON.stringify(this));
}
}
func2();//this={"a":"aaa"} 指向全局
b.func2 = func2;//将函数给对象
b.func2();//this={"a":"aaa"} 指向全局
function ObjectA(a,b){
this.a = a;
this.b = b;
this.func4=()=>{
console.log('this='+JSON.stringify(this));
}
}
b.objecA2 = new ObjectA(1,2);
b.objecA2.func4()//this={"a":1,"b":2},func4函数调用时的当前对象为b.objectA2,上一层对象为b
4.this 的变更
可通过apply,call 方法更改当前要执行的函数的this 对象
可通过bind 方法永久变更执行函数的this 对象
箭头函数无法更改this 对象
4.1 call/apply用法
call 和 apply 使用类似,唯一的区别是call 传递原函数的参数需要一个一个传入,而 apply 则是传入一个数组
'use strict'
this.a= 'aaa';//给全局this赋值
console.log("全局this:"+JSON.stringify(this));;//全局this:{"a":"aaa"}
var c = {
d:'111',
e:'222'
}
function func5(a,b) {
console.log('param a='+a+';param b='+b+';this='+JSON.stringify(this));
}
func5(1,2);//param a=1;param b=2;this=undefined
func5.call(c,1,2)//param a=1;param b=2;this={"d":"111","e":"222"},this更改为c对象
func5.apply(c,[1,2])//param a=1;param b=2;this={"d":"111","e":"222"},this更改为c对象
var func6=(a)=>{
console.log('param a='+a+';this='+JSON.stringify(this));
}
func6.call(c,1);//param a=1;this={"a":"aaa"},无法变更this指向
4.2 bind 用法
bind的用法和call 类似,不同是bind后返回一个新函数
var object3={
key:'yyyy'
}
function func7(a,b) {
console.log('param a='+a+';param b='+b+';this='+JSON.stringify(this));
}
func7(2,3)//param a=2;param b=3;this=undefined
var func8=func7.bind(object3)
func8(4,5)//param a=4;param b=5;this={"key":"yyyy"},this更改为object3
var func9=(a)=>{
console.log('param a='+a+';this='+JSON.stringify(this));
}
func9(2);//param a=2;this={"a":"aaa"}
var func10 = func9.bind(object3)
func10(1);//param a=1;this={"a":"aaa"} 箭头函数无法变更