ES5、ES6、ES7、ES8
ES5
- Strict Mode
在JS文件或是函数的顶部添加"use strict"即可启用严格模式。
"use strict";
function strict() {
"use strict";
}
在严格模式下运行脚本,不少导致提醒或bug行为的事情会抛出错误,例如:
(1)变量声明必须用var
在常规模式下,如果我们声明一个变量时省略了var关键字,解析引擎会自动将其声明为全局变量,但在严格模式下,会直接抛出异常,不会为我们转为全局变量
function strict() {
'use strict';
myVariable = 3; //Uncaught ReferenceError: myVariable is not defined
}
(2)禁止删除变量和对象中不可删除的属性
通过var声明的变量是不可删除的,在常规模式下,试图删除会静默失败,但在严格模式下会显式抛出异常;同样的,试图删除对象中不可删除的属性也会显式报错:
'use strict';
var a = 3;
delete a; //Uncaught SyntaxError: ...
delete Object.prototype; //Uncaught TypeError: ...
var animal = {};
Object.defineProperty(animal, 'name', {
configurable: false,
value: 'GOT'
});
delete animal.name; //Uncaught TypeError: ...
(3) 禁止对象属性重名
常规模式下,如果我们在对象中定义重复的属性,后定义的值会覆盖先定义的那个,ES5的严格模式规定,对象中不允许定义重复的属性,否则会显式报错。
'use strict';
var animal = {
name: 'BABY'
name: 'HUA'
};
console.log(person.name); // Uncaught SyntaxError: Unexpected identifier
(4)禁止函数参数同名
严格模式要求命名函数的参数必须唯一。
'use strict';
var b = 0;
function sum(a, a, c) { //Uncaught SyntaxError: ...
return a + b + c;
}
console.log(sum(1, 2, 3)); // Uncaught SyntaxError: Duplicate parameter name not allowed in this context
只能在脚本的顶级或者函数内部声明函数。在if语句中声明函数会报错:
'use strict';
if (true) {
function show() {
// ...
}
}
(5)禁止使用八进制数字
以0开头的八进制数字常常会让开发者迷惑,严格模式禁止以0开头的八机制表示法,另外,ES6已经支持新的语法标准,八进制以0o来表示,这样一来就与16进制的0x形成统一的语法格式
'use strict';
var a = 017; //Uncaught SyntaxError: Octal literals are not allowed in strict mode.
var b = 0o17; //ES6 Octal syntax: 8 + 7 = 15
(6) 禁止使用with语句.
'use strict';
var name = 'GOT';
var animal = getAminal();
with(animal) { //Uncaught SyntaxError: Strict mode code may not include a with statement
name = newName;
}
(7)强制为eval创建新作用域
常规模式下,使用eval函数可能会影响当前作用域或全局作用域,给程序的运行结果带来不确定性,严格模式为JavaScript程序创建了第三种作用域:eval作用域。eval函数中的字符串只能在eval作用域内运行,其结果不会影响外层作用域,下面这两种形式都可以使eval在严格模式下运行
'use strict';
function show() {
eval("var x = 10");
alert(x); // Uncaught ReferenceError: x is not defined
}
show();
(8)eval和arguments
严格模式下,禁止使用eval和arguments作为标识符,也不允许读写他们的值;
'use strict';
var eval = 19; // Uncaught SyntaxError: Unexpected eval or arguments in strict mode
var arguments = 'hello';
(9)抑制this
非严格模式下,apply和call方法,null或undefined转成全局对象;严格模式下,函数的this始终是指定的值;
'use strict';
var a = 'hello';
function show() {
alert(this.a); // Uncaught TypeError: Cannot read property 'a' of null
}
show.call(null);
2. JSON对象
JSON用于js原生对象和json字符串之间的转换。
JSON.parse(text [, reviver])
JSON.parse接受文本(JSON格式)并转换成一个ECMAScript值。将json字符串转成js原生对象;
var str = '{"result":true, "count":42}';
var jsonObj = JSON.parse(str);
console.log(jsonObj); // {result: true, count: 42}
console.log(typeof jsonObj); // object
JSON.stringify()
将一个js原生对象转化为json字符串;
var obj = { name: 'Heller', age: 14};
var jsonstr = JSON.stringify(obj);
console.log(jsonstr); // {"name":"Heller","age":14}
console.log(typeof jsonstr); //string
4. Object对象方法扩展
Object.defineProperty()
Object.defineProperty(obj, prop, descriptor)
descriptor:
数据描述符:
configurable: false,
enumerable: false,
value,
writable: false
存取描述符:
configurable: false,
enumerable: false,
set: undefined,
get: undefined
默认情况下,使用 Object.defineProperty() 添加的属性值(不是修改定义的属性)是不可修改(immutable)的,不可枚举的,不可删除的
var person = {};
Object.defineProperty(person, 'name', {
value: 'Hee'
});
console.log(person.name); // 'Hee'
person.name = 'Arrow';
console.log(person.name); // 'Hee' , 因为writable默认是false,不可修改
通过赋值操作添加的普通属性是可枚举的,在枚举对象属性时会被枚举到(for…in 或 Object.keys 方法),可以改变这些属性的值,也可以删除这些属性。
configurable
当且仅当该属性的 configurable 键值为 true 时,该属性的描述符才能够被改变,同时该属性也能从对应的对象上被删除。
默认为 false。
enumerable
当且仅当该属性的 enumerable 键值为 true 时,该属性才会出现在对象的枚举属性中。
默认为 false。
var person = {};
Object.defineProperty(person, 'name', {
value: 'Hee',
writable: true, // 修改属性值,默认false,不可修改
configurable: true, // 删除属性,默认false,不可删除
enumerable: true // 可枚举(使用for...in或Object.keys()),默认false,不可枚举
});
console.log(person.name); // 'Hee'
person.name = 'Arrow';
console.log(person.name); // 'Arrow' , writable为true,可修改
for (var i in person) {
console.log(i); // name, enumerable为true时才可以for..in
}
console.log(Object.keys(person)); // ["name"]