原文链接:
为什么想到写这么一篇文章呢,来源在于回答一个 SG上面的问题。那么问题是这样子的。
var a = 2; function foo(){ console.log(this.a);}foo();
以上代码,执行的结果是什么??
如果你回答是2,那么对了多少?
只能说对了一半,为什么呢? 其实是题主的问法有问题,他没有规定环境,所以答案很多,
直接在浏览器里面如下写法执行确实会输出2,没有问题。
但是如果在 nodejs里面, 大家考虑过么?
结果是可能是2,可能是 undefined。 现在有人是不是蒙圈了,不知道为什么。那么解析的文章在
甚至还有后续,可以看 sg上的原问题,
在评论中讨论到了一个问题,如果在浏览器中使用 ‘严格模式’, 会怎么样?
结果就是会报错,错误如下,是不是出乎大家的意料,
Uncaught TypeError: Cannot read property 'a' of undefined(…)
那么为什么呢? 我们打印下 this 关键字看看, 发现是 undefined。 我操,这跟我们的想法不符合啊,为何不是window这个全局变量了?? 这一切的原因在于 "use strict"
那么什么是严格模式,mozile的官方文档解释在这里
主要注意点在 “Changes in strict mode” 这个栏目下,“ Securing JavaScript” 第一条
First, the value passed as this to a function in strict mode is not forced into being an object (a.k.a. "boxed"). For a normal function, this is always an object: either the provided object if called with an object-valued this; the value, boxed, if called with a Boolean, string, or number this; or the global object if called with an undefined or null this. (Use , [apply
]( or [bind]( to specify a particularthis.) Not only is automatic boxing a performance cost, but exposing the global object in browsers is a security hazard, because the global object provides access to functionality that "secure" JavaScript environments must restrict. Thus for a strict mode function, the specified this is not boxed into an object, and if unspecified, this will be undefined:"use strict";function fun() { return this; } console.assert(fun() === undefined); console.assert(fun.call(2) === 2); console.assert(fun.apply(null) === null); console.assert(fun.call(undefined) === undefined); console.assert(fun.bind(true)() === true);
意思就是不会在默认的给function指定一个this对象了。 一般情况下,我们的function一定会有一个调用对象,不管是字符还是数组什么的,或者是全局变量,这种转换很损耗性能,而且危险,因为暴露了全局对象,所以严格模式下,不会再封装this对象了,如果没有,就是 undefined。
以上就是我们执行出来,报错的原因。至于这个模式到底好不好呢? 其实有些争议的,很多人写js已经习惯了这些各种变化,或者说是为方便吧,但是很多刚开始写的人很不习惯,甚至搞不明白,仁者见仁智者见智吧。
一篇简单的探索,这个严格模式 出来很早了,很多人都有写过,而且官方文档很详细。当然更关键的是你不使用也没有任何问题,一旦使用就要注意了哦。