this 的值是运行时计算出来的
let user = { name: "John" };
let admin = { name: "Admin" };
function sayHi() {
alert( this.name );
}
// 在两个对象中使用相同的函数
user.f = sayHi;
admin.f = sayHi;
// 这两个调用有不同的 this 值
// 函数内部的 "this" 是“点符号前面”的那个对象
user.f(); // John(this == user)
admin.f(); // Admin(this == admin)
admin['f'](); // Admin(使用点符号或方括号语法来访问这个方法,都没有关系。)
没有对象的情况下
- 在严格模式下,函数中的 this 是 undefined。
- 在非严格模式下,this 是全局对象(浏览器中是 window 对象)。
function showThis() {
console.log(this);
}
showThis(); // 在非严格模式下,this指向全局对象
箭头函数没有自己的this
let user = {
firstName: "Ilya",
sayHi() {
let arrow = () => console.log(this.firstName);
arrow();
}
};
user.sayHi(); // Ilya
调用函数时指定this
function say(phrase) {
alert(this.name + ': ' + phrase);
}
let user = { name: "John" };
let admin = { name: "Admin" };
say.call(user, "Hello"); // John: Hello
say.call(admin, "Hello"); // Admin: Hello
say.apply(user, ["Hello"]); // John: Hello
say.apply(admin, ["Hello"]); // Admin: Hello
say.bind(user, "Hello")(); // John: Hello
say.bind(admin, "Hello")(); // Admin: Hello
例子
在对象字面量中使用 “this”
function makeUser() {
return {
name: "John",
ref: this
};
}
let user = makeUser();
alert( user.ref.name ); // 结果是什么?
因为在调用 makeUser
函数时,不是通过对象调用的,所以 this
是 undefined
。因此,user.ref
是 undefined
,访问 user.ref.name
会导致错误。
反例:
function makeUser() {
return {
name: "John",
ref() {
return this;
}
};
}
let user = makeUser();
alert( user.ref().name ); // John
这里正常的原因是 ref
是一个方法,通过 user.ref()
调用时,this才被确定下来。
创建一个计算器
创建一个有三个方法的 calculator
对象:
read()
提示输入两个值,并将其保存为对象属性,属性名分别为 a 和 b。sum()
返回保存的值的和。mul()
将保存的值相乘并返回计算结果。
let calculator = {
// ……你的代码……
};
calculator.read();
alert( calculator.sum() );
alert( calculator.mul() );
let calculator = {
read(a,b){
this.a = +prompt();
this.b = +prompt();
},
sum(){
return this.a + this.b
},
mul(){
return this.a * this.b
}
};
calculator.read();
alert( calculator.sum() );
alert( calculator.mul() );
链式(调用)
有一个可以上下移动的 ladder
对象:
let ladder = {
step: 0,
up() {
this.step++;
},
down() {
this.step--;
},
showStep: function() { // 显示当前的 step
alert( this.step );
}
};
现在,如果我们要按顺序执行几次调用,可以这样做:
ladder.up();
ladder.up();
ladder.down();
ladder.showStep(); // 1
ladder.down();
ladder.showStep(); // 0
let ladder = {
step: 0,
up() {
this.step++;
return this;
},
down() {
this.step--;
return this;
},
showStep: function() { // 显示当前的 step
alert( this.step );
return this
}
};