ES5 严格模式
年份 | ECMA 版本 |
---|---|
1997 | 1.0 发布 |
1998 | 2.0 发布 |
1999 | 3.0 JS 通行标准 |
2007 | 4.0 草案 雅虎、微软、谷歌反对,只有 Mozilla 支持该草案 |
2008 | 终止 4.0 草案,求同存异后,将可改善部分纳入 3.1 ,发布 3.1 |
2009 | 5.0 发布,争议的 Harmony 分为 JS.NEXT 和 JS.NEXT.NEXT |
2011 | 5.1 发布,成为 ISO 国际标准,与 3.0 地位相同,几乎基于 3.0 |
2013 | ES6 版本不再新增内容,ES6 等同于 JS.NEXT |
2013 | ES6 草案发布 |
2015 | ES6 正式发布,命名为 ECMAScript2015 |
JS.NEXT.NEXT 更名为 ES7 |
从 ES5
开始,JavaScript 提供了两种运行模式,即正常模式和严格模式。需要注意的是,IE9
及以下版本的 IE
浏览器不支持严格模式。
严格模式的使用
使用字符串在全局进行声明
'use strict';
使用 'use strict'
作为表达式,不会导致报错。即使浏览器不支持严格模式,也不会出现错误。
在函数内部使用
在企业开发中,通常在函数内部使用严格模式,全局使用较为少见。
(function () {
'use strict';
// 函数内部代码
})();
严格模式的作用
with 语句
with
语句能够改变作用域,填入作用域名称后,会在该作用域中查找变量。此外,使用 with
会增加作用域解析的开销,影响性能。
var globalA = '全局';
var obj = {
a: 'obj中的a',
};
function test() {
var functionA = 'test函数中的a';
with (obj) {
console.log(a);
}
}
test();
在严格模式下的 with
严格模式禁止使用 with
语句,尝试使用会导致语法错误。
'use strict';
var globalA = '全局';
var obj = {
a: 'obj中的a',
};
function test() {
var functionA = 'test函数中的a';
with (obj) {
console.log(a);
}
}
test();
运行上述代码会抛出以下错误:
Uncaught SyntaxError: Strict mode code may not include a with statement
命名空间
在开发中,可能会出现同名变量或函数的情况。
function test() {
console.log(1);
}
function test() {
console.log(2);
}
test();
上述代码会打印出第二个 test
函数的结果。
解决命名冲突的方法
通过命名空间或模块化开发,可以避免命名冲突。
window.onload = function () {
init();
};
function init() {
initSlider();
initSidebar();
}
var initSlider = (function () {
var sliderValue = 1;
console.log(sliderValue);
})();
var initSidebar = (function () {
var sidebarValue = 1;
console.log(sidebarValue);
})();
未使用模块化时的命名空间管理
在早期多人协作开发中,可以通过对象嵌套的方式管理命名空间,防止命名冲突。
var namespace = {
header: {
Jenny: {
a: 1,
b: 2,
},
Ben: {
a: 3,
b: 4,
},
},
sidebar: {
Crystal: {
a: 5,
b: 6,
},
},
};
// 使用命名空间访问变量
console.log(namespace.header.Ben.a);
caller 和 callee
在严格模式下,caller
和 callee
属性无法访问。
'use strict';
function test() {
console.log(arguments.callee);
}
test(1);
执行上述代码会抛出以下错误:
Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
严格模式下的变量声明
在严格模式下,必须显式声明变量,否则会导致错误。
'use strict';
var a = (b = 1);
执行上述代码会抛出错误:
'use strict';
function test() {
var a = (b = 1);
}
test();
执行上述代码同样会抛出错误:
严格模式下的 this
'use strict';
console.log(this);
在全局环境中,this
指向 window
对象。
函数内部的 this
在严格模式下,未绑定的 this
为 undefined
。
'use strict';
function test() {
console.log(this);
}
test();
上述代码输出 undefined
。
严格模式下的函数形参
严格模式下,函数参数不能有重复的名称。
'use strict';
function test(a, a) {
console.log(a, a);
}
test(1, 2);
执行上述代码会抛出语法错误:
严格模式下的对象属性
在严格模式下,对象中不允许存在重复的属性名。
'use strict';
var obj = {
a: 1,
a: 2,
};
console.log(obj.a);
上述代码不会报错,但只能访问到最后一个属性值。
eval 函数
在严格模式下,eval
拥有独立的作用域,无法向外部作用域添加变量。
'use strict';
eval('var a = 1; console.log(a);');
console.log(a);
上述代码在严格模式下,a
不会被定义在全局作用域,第二个 console.log(a)
会导致错误。