1. 程式人生 > >為javascript的JSON物件擴充套件forEach方法

為javascript的JSON物件擴充套件forEach方法

最近發現javascript的JSON物件沒有forEach這個方法,所以就自己動手擴充套件了一下,做個記錄,方便以後使用。

1. Object prototype forEach

· 最初的程式碼

if (!Object.prototype.forEach) {
    Object.prototype.forEach = function(fn) {
        try {
            for (var key in this) {
                fn.call(this, this[key], key, this);
            }
        } catch
(e) { throw new TypeError(); } } }

· 測試

var obj = {"a": 1,"b": 2};

obj.forEach(function(value, key, json){
    console.log(value, key, json);
    /*
    列印結果:
    1 "a" Object {a: 1, b: 2}
    2 "b" Object {a: 1, b: 2}
    function (fn) {
        try {
            for (var key in this) {
                fn.call(this, this[key], key, this);
            }
        } catch (e) {
            throw new TypeError();
        }
    } "forEach" Object {a: 1, b: 2}
    */
})

· 分析

以上測試結果,基本符合預期,不過有一個問題:在自定義方法的最後,把方法函式體本身也枚舉出來了。為了解決這一問題,可以採用一個折中的辦法:hasOwnProperty(),即確定某屬性是否是物件本身的屬性。

· 最終版(支援IE6+)

//  @support: IE6+, Firefox, Chrome

if (!Object.prototype.forEach) {
    Object.prototype.forEach = function(fn) {
        try {
            for (var key in this) {
                if
(this.hasOwnProperty(key)) { fn.call(this, this[key], key, this); } } } catch (e) { throw new TypeError(); } } }

· 測試

var obj = {"a": 1,"b": 2};

obj.forEach(function(value, key, json){
    console.log(value, key, json);
    /*
      列印結果:
      1 "a" Object {a: 1, b: 2}
      2 "b" Object {a: 1, b: 2}
     */
}

然後結果完全符合預期了,Oh,Yeah ! 但是對於處女座,你以為就醬紫結束了嗎?NO NO NO.

So, 請接著往下看

2. ECMAScript 5 defineProperty

在新版本的ECMAScript 5中,可以設定自定義物件的方法為不可列舉。支援IE9以上,具體設定如下:

//  @support: IE9+, Firefox, Chrome

if (!Object.prototype.forEach) {
    Object.prototype.forEach = function(fn) {
        try {
            for (var key in this) {
                fn.call(this, this[key], key, this);
            }
        } catch (e) {
            throw new TypeError();
        }
    }
}
/***************************************************/
try {
    Object.defineProperty(Object.prototype, "forEach", {
        enumerable: false //是否可列舉?false
    });
} catch (e) {
    //throw new TypeError();
    console.log(e);
}

· 測試

var obj = {"a": 1,"b": 2};

obj.forEach(function(value, key, json){
    console.log(value, key, json);
    /**
     *  列印結果:
     *  1 "a" Object {a: 1, b: 2}
     *  2 "b" Object {a: 1, b: 2}
     */
}

以上就是全文,歡迎留言。同時感謝@jslang(天際的海浪)的指點。