标签:第一个 原因 xiaomi apply 属性 array 因此 name 参数
var xiaoming = {
name: ‘小明‘,
birth: 1990,
age: function () {
var y = new Date().getFullYear();
return y - this.birth;
}
};
?
xiaoming.age; // function xiaoming.age()
xiaoming.age(); // 今年调用是25,明年调用就变成26了
在一个方法内部,this
是一个特殊变量,它始终指向当前对象,也就是xiaoming
function getAge() {
var y = new Date().getFullYear();
return y - this.birth;
}
?
var xiaoming = {
name: ‘小明‘,
birth: 1990,
age: getAge
};
?
xiaoming.age(); // 25, 正常结果
getAge(); // NaN
JavaScript的函数内部如果调用了this
,那么这个this
到底指向谁?视情况而定!!!
如果以对象的方法形式调用,比如xiaoming.age()
,该函数的this
指向被调用的对象,也就是xiaoming
,这是符合我们预期的。
如果单独调用函数,比如getAge()
,此时,该函数的this
指向全局对象,也就是window
。
如果这么写:
var fn = xiaoming.age; // 先拿到xiaoming的age函数
fn(); // NaN
也是不行的!要保证this
指向正确,必须用obj.xxx()
的形式调用!
由于这是一个巨大的设计错误,要想纠正可没那么简单。ECMA决定,在strict模式下让函数的this
指向undefined
(即非对象调用函数情形),因此,在strict模式下,你会得到一个错误:
‘use strict‘;
?
var xiaoming = {
name: ‘小明‘,
birth: 1990,
age: function () {
var y = new Date().getFullYear();
return y - this.birth;
}
};
?
var fn = xiaoming.age;
fn(); // Uncaught TypeError: Cannot read property ‘birth‘ of undefined
这个决定只是让错误及时暴露出来,并没有解决this
应该指向的正确位置。
如果有嵌套函数:
‘use strict‘;
?
var xiaoming = {
name: ‘小明‘,
birth: 1990,
age: function () {
function getAgeFromBirth() {
var y = new Date().getFullYear();
return y - this.birth;
}
return getAgeFromBirth();
}
};
?
xiaoming.age(); // Uncaught TypeError: Cannot read property ‘birth‘ of undefined
结果又报错了!原因是this
指针只在age
方法的函数内指向xiaoming
,在函数内部定义的函数,this
又指向undefined
了!(在非strict模式下,它重新指向全局对象window
!)
修复的办法也不是没有,我们用一个that
变量首先捕获this
:
‘use strict‘;
?
var xiaoming = {
name: ‘小明‘,
birth: 1990,
age: function () {
var that = this; // 在方法内部一开始就捕获this
function getAgeFromBirth() {
var y = new Date().getFullYear();
return y - that.birth; // 用that而不是this
}
return getAgeFromBirth();
}
};
?
xiaoming.age(); // 25
这两个函数用来显示指定函数调用的this
的指向。
要指定函数的this
指向哪个对象,可以用函数本身的apply
方法,它接收两个参数,第一个参数就是需要绑定的this
变量,第二个参数是Array
,表示函数本身的参数。
function getAge() {
var y = new Date().getFullYear();
return y - this.birth;
}
?
var xiaoming = {
name: ‘小明‘,
birth: 1990,
age: getAge
};
?
xiaoming.age(); // 25
getAge.apply(xiaoming, []); // 25, this指向xiaoming, 参数为空
call
与apply
功能类似,区别为:
apply()
把参数打包成Array
再传入;
call()
把参数按顺序传入。
Math.max.apply(null, [3, 5, 4]); // 5
Math.max.call(null, 3, 5, 4); // 5
标签:第一个 原因 xiaomi apply 属性 array 因此 name 参数
原文地址:https://www.cnblogs.com/biwangwang/p/14263179.html