“”
ES5新增的内容
近期在开发React & React Native项目时, 经常有用到es6, 准备整理一下常用的es6内容, 在这之前先整理并复习一下es5的内容.
es5 各浏览器兼容性请参考http://kangax.github.io/compat-table/es5/
es5新增的内容并不多, 主要有:
严格模式
(注:在es6中并不需要使用严格模式)
可以在文件首行, 或函数体内首行加入’use strict’来把整个作用域变成严格模式
在严格模式下,会有如下一些限制:
- 禁止使用 with 语句
- 重名的属性会报错,重名的函数参数会报错
- 未声明的变量赋值直接报错,而不是变成全局变量
- 函数默认的 this 将变成 undefined 而不是默认指向 window
- 对只读属性进行写操作,删除不可删除属性,对不可拓展的对象添加属性均会抛出异常
JSON API支持
原生支持JSON.parse与JSON.stringify
对象 API扩展
定义getter setter:
var obj = {};
Object.defineProperty(obj, "name", {
get: function() {
return name.toUpperCase();
},
set: function(n) {
name=n;
}
})
定义一个对象的属性是否可以修改、是否可以删除、是否可以配置, 是否可以添加
Object.defineProperty( obj, "value", {
value: true,
writable: false,
enumerable: true,
configurable: true,
extensible: true,
});
冻结一个对象,冻结分两种:
- Object.seal(obj), 使对象的属性配置无法修改, 属性不能添加,等价于给每一个属性都设置成 configurale=false
- Object.freeze(obj),除了 seal 之外,它还会是属性值本身无法被修改,相当于对每个属性同时进行了 configurable=false 和 writable=false
调用对象父类原型上的方法: Object.getPrototypeOf(object):
function Person(){
this.method1 = function(){alert(1)}
}
Person.prototype.method2 = function(){alert(2);}
function Man(){
this.m1 = function(){
Object.getPrototypeOf(this).method1();
}
}
Man.prototype = new Person();
Man.prototype.m2 = function(){
Object.getPrototypeOf(this).method2();
}
var man = new Man();
man.m1();
man.m2();
获取对象中属性的ECMAScript对象: Object.getOwnPropertyDescriptor(object, propertyname)
var obj = {};
obj.a = "abc";
var descriptor = Object.getOwnPropertyDescriptor(obj, "a");
for(var prop in descriptor){
document.write(prop + ': ' + descriptor[prop]);
document.write("<br />");
}
/*
configurable: true
enumerable: true
value: abc
writable: true
*/
用 ECMAScript对象 设置为object中多个属性的值: object.defineProperties(object, descriptors):
var obj = {};
obj.a = "abc";
Object.defineProperties(obj,{
a:{
configurable: true,
enumerable: true,
value: 'aaa',
writable: false
}
});
var descriptor = Object.getOwnPropertyDescriptor(obj, "a");
for(var prop in descriptor){
document.write(prop + ': ' + descriptor[prop]);
document.write("<br />");
}
/*
configurable: true
enumerable: true
value: aaa
writable: false
*/
避免加新属性加入对象(Extensible设置为false): Object.preventExtensions(object):
var obj = { a: "1"};
Object.preventExtensions(obj);
document.write(Object.isExtensible(obj));//false
obj.newProp = 50;
document.write(obj.newProp);//undefined
建立一个原型为prototype,descriptors为ECMAScript对象的对象: Object.create(prototype, descriptors):
var a = Object.create({a:1,b:2}, {
c: {
value: "large",
enumerable: true
},
d: {
value: "round",
enumerable: true
}
});
判断对象是否为锁定,冻结,不可扩展的:
Object.isSealed(object);
Object.isFrozen(object);
Object.isExtensible(object);
遍历对象属性:
- Object.getOwnPropertyNames 返回一个由对象属性名组成的数组(包含不可枚举的)
- Object.keys 返回一个由对象可枚举的属性组成的数组.
Array API 增强
- indexOf 返回某项内容在数组中的下标, 类同String.indexOf, 还有lastIndexOf
var arr = ['apple','orange','pear'];
console.log("found:", arr.indexOf("orange") != -1);
- filter 遍历数组, 根据每次回调的return值, true保留, false过滤, 最终返回一个新数组
var arr = [
{"name":"apple", "count": 2},
{"name":"orange", "count": 5},
{"name":"pear", "count": 3},
{"name":"orange", "count": 16},
];
var newArr = arr.filter(function(item){
return item.name === "orange";
});
console.log("Filter results:",newArr);
- forEach 遍历数组, 每次回调中可以做一些操作
var arr = [1,2,3,4,5,6,7,8];
// Uses the usual "for" loop to iterate
for(var i= 0, l = arr.length; i< l; i++){
console.log(arr[i]);
}
console.log("========================");
//Uses forEach to iterate
arr.forEach(function(item,index){
console.log(item);
});
- map 遍历数组, 根据每次回调的return值, 最终返回一个新数组
var oldArr = [{first_name:"Colin",last_name:"Toh"},{first_name:"Addy",last_name:"Osmani"},{first_name:"Yehuda",last_name:"Katz"}];
function getNewArr(){
return oldArr.map(function(item,index){
item.full_name = [item.first_name,item.last_name].join(" ");
return item;
});
}
console.log(getNewArr());
- every 遍历数组, 根据每次回调的return值, 如果都为true, 则最终返回true, 反之最终返回false
var arr = [ 1, 2, 3, 4];
var result = arr.every( function( item, index, array ){
console.log( item, index, array );
return item < 3;
});
1 0 [1, 2, 3, 4]
2 1 [1, 2, 3, 4]
3 2 [1, 2, 3, 4]
result -> false
- some 遍历数组, 根据每次回调的return值, 如果都为false, 则最终返回false, 反之最终返回true
var arr = [ 1, 2, 3, 4];
var result = arr.some( function( item, index, array ){
console.log( item, index, array);
return item > 2;
});
->
1 0 [1, 2, 3, 4]
2 1 [1, 2, 3, 4]
3 2 [1, 2, 3, 4]
restule -> true
- reduce
reduce在这里有减少
的意思,那reduce到底是干什么用的呢?说实话我也不太理解,看看比较官方的解释:The method applies a function against an accumulator and each value of the array (from left -to- right ) to reduce it to a single value . 自己慢慢的理解吧,我们先看看怎么使用吧,用的多了自然就明白了:
var arr = [1,2,3,4];
var newArr = arr.reduce(function(previousValue, currentValue, currentIndex, array){
console.log(previousValue, currentValue,currentIndex);
return previousValue + currentValue;
});
1 2 1
3 3 2
6 4 3
newArr -> 10
从运行结果看,initialValue参数指定了previousValue的初始值,更重要的是,这次数组是从第1个位置开始遍历,而不再是从第2个位置开始了。 现在回过头来,对照这两个例子,我相信你一定能够理解reduce的作用了。下面对于reduce的扩展会巩固你对reduce的理解:
if(!Array.prototype.reduce) {
Array.prototype.reduce = function (callback, initialValue) {
var previousValue = initialValue || this[0];//如果不指定intialValue,则默认为数组的第一个元素
//如果不指定initialValue,i从1开始遍历,否则就从0开始遍历
for (var i = initialValue?0:1; i < this.length; i++) {
//previousValue 累加每一次返回的结果
previousValue += callback(previousValue, this[i],i,this.toString());
}
return previousValue;
}
}
- reduceRight
reduce的作用完全相同,唯一的不同是,reduceRight是从右至左遍历数组的元素。