ECMAScript5 給出了一系列新的API接口,這些接口在新的瀏覽器中大部分是被支持的,IE9,Chrome,FirFor都支持,也有少量API不是所有瀏覽器都支持,以下內容僅介紹大部分被支持的API。利用新的API我們可以設計出非常靠譜的類,而且還能保持原有的javaScript的風格。
ECMAScript 5.1 (或僅 ES5) 是ECMAScript(基於JavaScript的規範)標準最新修正。 與HTML5規範進程本質類似,ES5通過對現有JavaScript方法添加語句和原生ECMAScript對象做合併實現標準化。以下瀏覽器都可以良好的支持ECMAScript5的行爲了:Opera 11.60+、
Internet Explorer 9+、Firefox 4+、Safari 5.1+、Chrome 13。
其中目前來看,IE9不支持嚴謹模式,但IE10是支持的。
要查看下自己的瀏覽器是不是兼容ECMAScript5,可以查看這個ECMAScript 5 兼容性表表,其中還可以觀察到其他瀏覽器的兼容情況。哎,苦逼的前端程序員,css有兼容性問題,js腳本也有兼容性問題,無語了。
Object.create(prototype, descriptors)
以指定的原型創建對象,並且可以(可選)的設置對象的屬性
function Poker(style, title, value) {
this.Style = style;
this.Title = title;
this.Value = value;
}
var pokerA = Object.create(new Poker("club", "A", 14));
alert(Poker.constructor); //function Function() { [native code] }
alert(new Poker().constructor); //function Poker(style, title, value) {
// this.Style = style;
// this.Title = title;
// this.Value = value;
// }
alert(Poker.constructor.prototype); //function Empty() {}
alert(Poker.prototype == new Poker().constructor.prototype); // true
alert(Poker.constructor.prototype == new Poker().constructor.prototype); // false
alert(new Poker().propertye); //undefined
alert(Poker.prototype == pokerA.constructor.prototype); //true
alert(Poker.constructor.prototype == pokerA.constructor.prototype); // false
alert(new Poker("club", "A", 14).Value); //14
alert(pokerA.Value); //14
上面的代碼寫了一堆邏輯表達式,就是證明一件事情,用Object.create構造的對象和用構造函數構造的對象在結果上沒有什麼差異。用Object.create的好處是原型鏈乾淨,網上有有給出了以下沒有Object.create的瀏覽器的解決同樣解決方案。以下代碼不但說明了Object.create的技術內幕,同時可以支持低版本的IE同樣可以實現乾淨的原型。
if (typeof Object.create !== 'function') {
Object.create = function(o) {
function F() { }
F.prototype = o;
return new F();
};
}
function Poker(style, title, value) {
this.Style = style;
this.Title = title;
this.Value = value;
}
var pokerA = Object.create(new Poker("club", "A", 14));
alert(Poker.constructor); //function Function() { [native code] }
alert(new Poker().constructor); //function Poker(style, title, value) {
// this.Style = style;
// this.Title = title;
// this.Value = value;
// }
alert(Poker.constructor.prototype); //function Empty() {}
alert(Poker.prototype == new Poker().constructor.prototype); // true
alert(Poker.constructor.prototype == new Poker().constructor.prototype); // false
alert(new Poker().propertye); //undefined
alert(Poker.prototype == pokerA.constructor.prototype); //true
alert(Poker.constructor.prototype == pokerA.constructor.prototype); // false
alert(new Poker("club", "A", 14).Value); //14
alert(pokerA.Value); //14
Object.defineProperty(object, propertyname, descriptor)
對指定的對象的一個屬性設置豐富的值控制
Object.defineProperties(object, descriptors)
對指定的對象的一組屬性提供豐富的值控制
function setPokerState(poker, proValue) {
if (arguments[0] instanceof Poker) {
Object.defineProperty(arguments[0], //爲一個對象設置一個屬性
"State", //屬性名稱是字符串
{//一組修飾對象
value: proValue, //值 默認是undefined
writable: true, //值是否只讀 默認是false
enumerable: false, //值是否可以被枚舉 默認false
configurable: true//屬性是否可以被改說刪除 默認false
}
)
}
}
var PokerA = Object.create(new Poker("club", "A", 14));
setPokerState(PokerA, 5);
alert(PokerA.State);
如果我們需要對賦值或取值有更多出來,可以給定set和get函數,不過set/get不能和value、writable同時使用。
function setPokerState(poker, proValue) {
if (arguments[0] instanceof Poker) {
Object.defineProperty(arguments[0], //爲一個對象設置一個屬性
"State", //屬性名稱是字符串
{//一組修飾對象
enumerable: false, //值是否可以被枚舉 默認false
configurable: true, //屬性是否可以被改說刪除 默認false
set: function(x) {
this.state = x <= 5 ? x : 5;
},
get: function() {
return this.state;
}
}
)
}
}
var PokerA = Object.create(new Poker("club", "A", 14));
PokerA.State=10;
如果我需要設置多個屬性的話,請看下面代碼演示
Object.defineProperties(
PokerA,
{
"backgroundImg": {
value: "images\\common\\hide.png",
enumerable: false, //不可以for 遍歷
writable: false//只讀
},
"forgroundImg": {
value: "images\\spade\\K.png",
enumerable: false, //不可以for 遍歷
writable: false//只讀
},
Image: {
get: function() {
return this.State == 0 ? this.backgroundImg : this.forgroundImg;
},
enumerable: true
}
}
);
如果要了解對象有哪些屬性被定義了,可以使用以下API
Object.getOwnPropertyDescriptor(object, propertyname)
返回屬性的定義
Object.getOwnPropertyNames(object)
返回所有屬性的名稱,哪怕說是不能枚舉的屬性
下面是一個demo
alert(Object.getOwnPropertyNames(PokerA).length); //4
var names = Object.getOwnPropertyNames(PokerA);
for (var i = 0; i < names.length; i++) {
alert(names[i] + "\n" +
Object.getOwnPropertyDescriptor(PokerA, names[i])
);
}
可以約定對象不能再擴展,但屬性的值可以改,也可以刪除
Object.preventExtensions(object)
防止新的屬性添加到對象
Object.isExtensible(object)
是否可添加屬性到對象
alert(Object.isExtensible(PokerA)); //true
Object.preventExtensions(PokerA);
alert(Object.isExtensible(PokerA)); //false
需要再嚴一點控制,可以使用如下api
Object.seal(object)
不能添加和刪除屬性
Object.isSealed(object)
alert(Object.isSealed(PokerA)); //true
Object.seal(PokerA);
alert(Object.isSealed(PokerA)); //false
如果要再嚴一點,完全封死對象,可以
Object.freeze(object)
防止現有屬性和屬性值的修改,並防止新特性的添加。
Object.isFrozen(object)
最後如果想要得到對象原型,可以用
Object.getPrototypeOf(object)
關於object的就差不多上面這些了。然後看下ECMAScript5再其他對象上的擴展的一些靜態成員
Array.isArray
啥意思不必說了
alert(Array.isArray([])); //true
alert(Array.isArray({})); //false
Array.IndexOf
Array.lastIndexOf
一看就是好東西呀,不解釋了
alert(["Hello", "javaScript", "ECMAScript", "HTML5"].indexOf("javaScript"));//1
alert(["Hello", "javaScript", "ECMAScript", "HTML5"].lastIndexOf("javaScript"));//1
Array.every
對數組的每個元素進行一個callback的條件檢查,查看是否存在有不符合條件的元素。類似linq的all
var arr1 = "Charles,Mark,Bill,Vincent,William,Joseph".split(",");
alert(arr1.every(
function(item, index) {
return item.length < 5;
}
)
); //false
alert(arr1.every(
function(item, index) {
return item.length < 10;
}
)
)//true
Array.some
是判斷數組有沒有符合條件的元素,類似linq的any
var arr1 = "Charles,Mark,Bill,Vincent,William,Joseph".split(",");
alert(arr1.some(
function(item, index) {
return item.length < 5;
}
)
); //true
alert(arr1.some(
function(item, index) {
return item.length < 10;
}
)
)//true
如果需要對每一個元素執行一段處理性的代碼可以用
Array.forEach
var arr1 = "Charles,Mark,Bill,Vincent,William,Joseph".split(",");
arr1.forEach(
function(item, index) {
if (index % 2 == 0) {
arr1[index] = "name:" + item;
}
}
);
arr1.forEach(
function(item, index) {
alert(item);
}
);
其實forEach最好是直接處理值,如果要改變數組最好用
Array.map
var arr1 = "Charles,Mark,Bill,Vincent,William,Joseph".split(",");
var arr2 = arr1.map(
function(item, index) {
if (item.indexOf("ll") > -1) {
return item;
}
}
);
arr2.forEach(
function(item, index) {
alert(item);
}
);
如果是要過濾數組的話,可以用
Array.filter
var arr1 = "Charles,Mark,Bill,Vincent,William,Joseph".split(",");
var arr2 = arr1.filter(
function(item, index) {
if (item.indexOf("ll") > -1) {
return true;
}
}
);
arr2.forEach(
function(item, index) {
alert(item);
}
);
如果要做疊加器處理可以用
Array.reduce
var arr1 = "Charles,Mark,Bill,Vincent,William,Joseph".split(",");
var arr2 = arr1.reduce(
function(item, next) {
return item + "][" + next;
}
);
alert("[" + arr2 + "]");//[Charles][Mark][Bill][Vincent][William][Joseph]
還有一個反向處理
Array.reduceRight
var arr1 = "Charles,Mark,Bill,Vincent,William,Joseph".split(",");
var arr2 = arr1.reduceRight(
function(item, next) {
return item + "][" + next;
}
);
alert("[" + arr2 + "]"); //[Joseph][William][Vincent][Bill][Mark][Charles]
現在Array的處理都接近linq了!!!
Date().toJSON()
含義一眼看出,內置就是爽
alert(new Date().toJSON());
alert(new Date(2012, 11, 12).toJSON()); //2012-12-11T16:00:00.000Z
字符串給了一個trim,啥都沒有好說了,你來晚了
alert("[" + " Hello ".trim() + "]"); //[Hello]
總體來說,新的API還是很給力的啊