var Test={
UA:navigator.userAgent,
isAndroid:(function(){
console.log(this.UA);
// return /android/gi.test(this.UA);
})()
}
调用 Test.isAndroid
结果为undefined
此时的this
指向的不是Test
么
var Test={
UA:navigator.userAgent,
isAndroid:(function(){
console.log(this.UA);
// return /android/gi.test(this.UA);
})()
}
调用 Test.isAndroid
结果为undefined
此时的this
指向的不是Test
么
var Test = (function () {
var UA = navigator.userAgent;
return {
UA: UA,
isAndroid: /android/gi.test(UA)
}
})();
var Test={
UA:navigator.userAgent,
isAndroid:function(){
console.log(this.UA);
return this.UA;
}.call(Test)
}
正如前面几位大神说的,isAndroid的值是一个立即执行的匿名函数,执行时的执行上下文是window,所以this.UA就是undefined了!你可以用call或者apply调用并传入Test作为它的执行下上文,并且return this.UA,此时Test.isAndroid的值才是你想要的结果
因为this
是在Test
声明阶段被使用的,那个时候Test
确实还是undefined
.
要么把代码改下:
var Test={
UA:navigator.userAgent,
isAndroid: function(){
console.log(this.UA);
// return /android/gi.test(this.UA);
}
};
console.log(Test.isAndroid());
this
指向调用该函数的对象,IIFE不是Test
调用的,编译的时候就执行了。所以是undefined
。
//如果非要用IIFE,可以这么写
var Test={
UA:navigator.userAgent
}
Test.isAndroid=(function(that){
console.log(that.UA);
return /android/gi.test(this.UA);
})(Test);
console.log(Test.isAndroid);
isAndroid引用的是立即运行的匿名函数。
匿名函数的this指向window,严格模式下指向undefined。
UA是undefined,所以test.isAndroid会打印undefined。
你可以在程序前面加上 window.UA="chrome"再看看打印内容。
10 回答11.7k 阅读
2 回答3.2k 阅读✓ 已解决
2 回答4.2k 阅读✓ 已解决
3 回答1.9k 阅读✓ 已解决
3 回答1.7k 阅读✓ 已解决
3 回答2.7k 阅读✓ 已解决
2 回答1.7k 阅读✓ 已解决
var Test = {}
是一个声明+赋值的运算,赋值就是先对等号右边的表达式求值,然后将结果赋给等号左边的变量——换句话说:只有赋值成功后才能访问Test
。而
isAndroid
是在对等号右边表达式求值时就运行的(IIFE),此时由于Test
还没有完成赋值,IIFE 实际访问的this
是window
,而window.UA
是不存在的,因此undefined
无误。JavaScript 是动态语言,
this
的指向是在代码执行时由解释器决定的,你写的这个isAndroid
本质上是编译型语言里的getter
方法,所以不要用 IIFE 来在声明时自动求值。如果你不想用
Test.isAndroid()
这样的方式来访问this.UA
,你可以写 JavaScript 的get isAndroid
方法,这个要看你使用的 ES 版本来决定具体的写法了,可上网搜索 JavaScript getter/setter 作进一步学习。补充一个样本,对浏览器支持有要求,自行做转换或找 shim 支持: