我们在写js时,特别是用到回调函数时,经常会发现this指代的对象总是可能脱离自己的思路而发生改变。面向对象语言的特性告诉我们this始终指代它的调用者,而在js中回调函数中内部的this默认指向全局环境即最终上下文,所以很多时候我们不作this对象的声明绑定,就会发生指向错误,找不到我们想要的值。
- 函数声明式,没有return一个对象,此时函数内的this相当于全局window
function test(){
this.a = 1;
console.log(a);
}
test(); //1
console.log(a); //1
console.log(this.a); //1
console.log(window.a); //1
//局部变量
function test(){
var a = 1;
console.log(a); //1
console.log(this.a); //undefined
}
test();
- 作为对象方法调用,this指代上级对象
function test(){
console.log(this.x);
}
var o = {};
o.x = 1;
o.m = test;
o.m(); // 1
- 作为构造函数调用,this指代new出的对象。构造函数一般首字母大写,需要用new来声明对象,区别普通function
var x = 2;
function Test() {
this.x = 1; //为了表明这时this不是全局对象
}
var o = new Test();
console.log(o.x); // 1
console.log(this.x); //2
- 函数有return对象的时候,this指向构造函数对象本身。return返回多个值,通过对象的属性访问。
function Test() {
this.b = 1; //this = Test{}
return {
a: 2
}
}
var o = new Test();
console.log(o.a); // 2
console.log(this.b); //undefined
//在JavaScript构造函数中:如果return值类型,那么对构造函数没有影响,实例化对象返回空对象;如果return引用类型(数组,函数,对象),那么实例化对象就会返回该引用类型;
function Super(a){
this.a=a;
return 123;
}
Super.prototype.sayHello=function(){
console.log("Hello")
}
function Super1(a){
this.a=a;
return {a:2};
}
Super1.prototype.sayHello=function(){
console.log("Hello")
}
console.log(new Super(1)); //返回Super{a:1},有原型方法sayHello
console.log(new Super1(2)); //返回Object{a:2},没有原型方法sayHello
- ES6中引入了箭头函数,箭头函数使用操作符=>定义。箭头函数不使用上面4种this绑定规则,而是根据外层作用域来决定this。foo内部的箭头函数创建时,foo函数内this绑定到obj1上,bar(箭头函数)的this也会绑定到obj1上,箭头函数内的this是不能被修改的。
function foo() {
// this.b = 1; //this = Test{}
return (a) => {
console.log(this.a);
};
}
var obj1 = { a: 2 };
var obj2 = { a: 3 };
var bar = foo.call(obj1);
bar.call(obj2); // 2
- 参考文献
1、JS中this的四种用法
网友评论