亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

《JavaScript程序設(shè)計(jì)》—— 標(biāo)準(zhǔn)對(duì)象 Object

Meils / 1128人閱讀

摘要:需要鏈接標(biāo)準(zhǔn)參考教程對(duì)象阮一峰標(biāo)準(zhǔn)構(gòu)造器函數(shù)可能是最重要的對(duì)象之一,盡管我們從來(lái)不會(huì)直接調(diào)用它。該方法返回被凍結(jié)的對(duì)象。

Object 需要鏈接: MDN —— Object JavaScript標(biāo)準(zhǔn)參考教程(Object對(duì)象)——阮一峰

標(biāo)準(zhǔn)構(gòu)造器函數(shù)Object可能是JavaScript最重要的對(duì)象之一,盡管我們從來(lái)不會(huì)直接調(diào)用它。每當(dāng)使用一個(gè)對(duì)象直接量時(shí),都會(huì)隱式調(diào)用它:

    var a = {};                // 等同于var a = new Object()
    var b = {x:1,y:2};        // 等同于var b = new Object({x:1,y:2});

構(gòu)造函數(shù)定義了數(shù)據(jù)類型,所以表達(dá)式var a = new Object()表明兩件事情:a是Object的一個(gè)實(shí)例,而a的原型是Object.prototype。我們用對(duì)象字面量創(chuàng)建的每個(gè)對(duì)象都會(huì)獲得由Object.prototype定義的行為

以下將討論幾個(gè)常用的主要的屬性方法 1. Object()
    // 首先,將Object作為構(gòu)造函數(shù)調(diào)用和對(duì)象字面量直接定義是等價(jià)的
    var o = {};
    var o2 = new Object();
    // 注意這里所說(shuō)的等價(jià)不是指相等,是指其本身和原型繼承相同
    
    // 當(dāng)然也可以
    var a = {};
    var a2 = new Object(a);
    console.log(a===a2);            // true
Object本身作為工具方法
    // 返回一個(gè)Object構(gòu)造器實(shí)例
    var obj = Object();
    console.log(obj instanceof Object);            // true
    
    // 返回一個(gè)字符串構(gòu)造器實(shí)例
    var str = Object("string");
    console.log(str instanceof Object);            // true     等價(jià)    new String("string")
    
    // 返回一個(gè)數(shù)字構(gòu)造器實(shí)例
    var num = Object(123);
    console.log(num instanceof Object);            // true        等價(jià)    new Number(123)
    
    // 返回一個(gè)布爾構(gòu)造器實(shí)例
    var boo = Object(true);                        // 等價(jià)    new Boolean(true)
    var boo2 = Object(false);                    
    console.log(boo instanceof Object && boo2 instanceof Object);    // true
    
    // null存在的意義在于對(duì)象引用之中,null值最初含義為:沒(méi)有引用任何對(duì)象
    // null型只能取null一個(gè)值,null值是一個(gè)字面量,但是對(duì)null進(jìn)行typeof結(jié)果為對(duì)象
    console.log(typeof null);                            // object
    console.log(Object(null) instanceof Object);        // true
    // 對(duì)null調(diào)用Object方法,返回一個(gè)空對(duì)象
    
    
    // undefined型也只能取undefined一個(gè)值,對(duì)undefined進(jìn)行typeof ,值為undefined
    console.log(typeof undefined);                        // undefined
    console.log(Object(undefined) instanceof Object);    // true
    // 也是返回一個(gè)空對(duì)象

Object本身當(dāng)作工具方法使用時(shí),可以將任意值轉(zhuǎn)為對(duì)象。這個(gè)方法常用于保證某個(gè)值一定是對(duì)象。如果參數(shù)是原始類型的值,Object方法返回對(duì)應(yīng)的包裝對(duì)象的實(shí)例

Object()傳入?yún)?shù)為基本類型值,則返回值為其類型的構(gòu)造函數(shù)的實(shí)例。

上面探討的是基礎(chǔ)類型值,那如果是引用類型值呢?

    var arr = [1,2,3];        
    console.log(Object(arr));            // 把原對(duì)象返回了
    console.log(Object(arr)===arr);        // true
    
    var fn = function () {};            // 把原函數(shù)返回了
    console.log(Object(fn));            // function () {}
    console.log(Object(fn)===fn);        // true
    
    var obj = {x:"obj.x"};
    console.log(Object(obj));            // [object Object]
    console.log(Object(obj)===obj);        // true
    
    // 一個(gè)判斷是否是對(duì)象的函數(shù)
    function judgeObj(obj) {
        return Object(obj)===obj? true : false;
    }
    
    console.log(judgeObj([]));            // true
    console.log(judgeObj(true));        // false
    console.log(judgeObj({}));            // true
    console.log(judgeObj(123));            // false
當(dāng)Object()傳入的參數(shù)是引用類型值,則會(huì)返回原對(duì)象; 2. Object.keys(obj)

Object.keys() 方法會(huì)返回一個(gè)由一個(gè)給定對(duì)象的自身可枚舉屬性組成的數(shù)組,數(shù)組中屬性名的排列順序和使用 for...in 循環(huán)遍歷該對(duì)象時(shí)返回的順序一致 (兩者的主要區(qū)別是 一個(gè) for-in 循環(huán)還會(huì)枚舉其原型鏈上的屬性)。

Enumerable條件限制,且不可枚舉原型鏈中的屬性
    // 無(wú)法枚舉到原型鏈中的屬性
    var obj = Object.create({y:20});
    obj.x = 10;
    console.log(Object.keys(obj));        // "x"
    
    // 無(wú)法枚舉Enumerable為false屬性
    Object.defineProperty(obj,"z",{
        value:"z",
        enumerable:false
    })
    console.log(Object.keys(obj));        // "x"
        
    // 對(duì)于數(shù)組對(duì)象
    var arr = ["a","b","c"];
    console.log(Object.keys(arr));        // "0,1,2"
    
    // 對(duì)于隨機(jī)排列的數(shù)組對(duì)象
    var obj_ramdom = {100:"a",2:"b",50:"c"};
    console.log(Object.keys(obj_ramdom));        // "2,50,100"
詳細(xì)說(shuō)明:MDN —— Object.keys() 3. Object.getOwnPropertyNames(obj)

Object.getOwnPropertyNames 返回一個(gè)數(shù)組,該數(shù)組對(duì)元素是 obj 自身?yè)碛械拿杜e或不可枚舉屬性名稱字符串。 數(shù)組中枚舉屬性的順序與通過(guò) for...in 循環(huán)(或 Object.keys)迭代該對(duì)象屬性時(shí)一致。 數(shù)組中不可枚舉屬性的順序未定義。

不受Enumerable條件限制,但不可枚舉原型鏈中屬性

如果你只要獲取到可枚舉屬性,查看 Object.keys 或用 for...in循環(huán)(還會(huì)獲取到原型鏈上的可枚舉屬性,不過(guò)可以使用hasOwnProperty()方法過(guò)濾掉)。

    // 無(wú)法枚舉到原型鏈中的屬性
    var obj = Object.create({y:20});
    obj.x = 10;
    console.log(
        Object.getOwnPropertyNames(obj)
    );                                    // "x"
    
    // 可以枚舉Enumerable為false的屬性
    Object.defineProperty(obj,"z",{
        value:"z",
        enumerable:false
    })
    console.log(
        Object.getOwnPropertyNames(obj)
    );                                    // "x,z"
        
    // 對(duì)于數(shù)組對(duì)象(length屬性為不可枚舉)
    var arr = ["a","b","c"];
    console.log(
        Object.getOwnPropertyNames(arr)
    );                                    // "0,1,2,length"
    
    // 對(duì)于隨機(jī)排列的數(shù)組對(duì)象
    var obj_ramdom = {100:"a",2:"b",50:"c"};
    console.log(
        Object.getOwnPropertyNames(obj_ramdom)
    );                                    // "2,50,100"
詳細(xì):MDN —— Object.getOwnPropertyNames() for-in、Object.keys、Object.getOwnPropertyNames特點(diǎn)區(qū)分 三者關(guān)于是否受Enumerable的限制測(cè)試
    
    var obj = {x:10,y:20};
    Object.defineProperty(obj,"z",{
        value:30,
        enumerable:false,
    });
    
    // for-in
    for (var a in obj) {
        console.log(a);                     // "x,y"
    }
    
    // Object.keys
    console.log(
        Object.keys(obj)                    // "x,y"
    );
    
    // Object.getOwnPropertyNames()
    console.log(
        Object.getOwnPropertyNames(obj)     // "x,y,z"
    );
三者關(guān)于是否可以枚舉原型鏈的測(cè)試
    function Test() {
        this.x = 10;
        this.y = 20;
    }
    Test.prototype.z = 30;        // z為原型鏈屬性
    var obj = new Test();
    
    
    // for-in
    for (var a in obj) {
        console.log(a)                         // "x,y,z"
    }
    
    // Object-keys
    console.log(
        Object.keys(obj)                       // "x,y"
    )

    
    // Object.getOwnPropertyNames()
    console.log(
        Object.getOwnPropertyNames(obj)        // "x,y"
    )

我們?nèi)绾斡洃浤兀烤陀涀钐厥獾模?/p> for-in:只有它可以枚舉原型鏈里的屬性,并且它也不是Object對(duì)象的方法 Object.getOwnPropertyNames():只有它可以享有Enumerable的"豁免權(quán)",不管如何設(shè)置只要是這個(gè)對(duì)象上的自有屬性都可以枚舉到! 對(duì)象屬性控制相關(guān)方法 四個(gè)相關(guān)的方法在這里先列出,這里要要提到數(shù)據(jù)屬性和訪問(wèn)器屬性

《JS高程》—— 數(shù)據(jù)屬性與訪問(wèn)器屬性

強(qiáng)薦:阮一峰 —— 屬性描述對(duì)象

4. Object.defineProperty()

Object.defineProperty() 方法會(huì)直接在一個(gè)對(duì)象上定義一個(gè)新屬性,或者修改一個(gè)對(duì)象的現(xiàn)有屬性, 并返回這個(gè)對(duì)象。

5. Object.getOwnPropertyDescriptor()

Object.getOwnPropertyDescriptor() 返回指定對(duì)象上一個(gè)自有屬性對(duì)應(yīng)的屬性描述符。(自有屬性指的是直接賦予該對(duì)象的屬性,不需要從原型鏈上進(jìn)行查找的屬性)

    // 采用Object.defineProperty定義的屬性,如果不顯示定義
    // enumerable,configurable,writable值默認(rèn)為false(與對(duì)象字面量相反)
    var obj = {};
    Object.defineProperty(obj,"x",{
        value:"obj.x"
    });
    
    
    // 使用Object.getOwnPropertyDescriptor()獲取屬性對(duì)象
    var obj_attr = Object.getOwnPropertyDescriptor(obj,"x");
    for (var i in obj_attr) {
        document.write(i+" : "+obj_attr[i]+"
") } // 默認(rèn)下數(shù)據(jù)屬性都是false
6. Object.defineProperties()

Object.defineProperties() 方法直接在一個(gè)對(duì)象上定義新的屬性或修改現(xiàn)有屬性,并返回該對(duì)象。

    var obj = {};
    Object.defineProperties(obj,{
        x:{
            value:"obj.x",
            writable:true,
            enumerable:true,
            configurable:true
        },
        y:{
            value:"obj.y",
            writable:true,
            enumerable:true,
            configurable:true
        },
        z:{
            value:"obj.z"
        }
    })
    
    console.log(Object.keys(obj));            // "x,y"    z屬性enumerable默認(rèn)為false
    // 當(dāng)然,z屬性的數(shù)據(jù)屬性都是false
沖突:

《JavaScript編程全解》:只要將get屬性與set屬性指定為相應(yīng)的函數(shù),就能夠定義一個(gè)只能夠通過(guò)訪問(wèn)器gettersetter來(lái)訪問(wèn)值的屬性。訪問(wèn)器與value屬性是互相排斥的,也就是說(shuō),如果指定了value屬性的值,訪問(wèn)器(包括getset)就會(huì)失效;反之,如果指定了訪問(wèn)器(getset中的某一個(gè)亦或是都存在),value屬性就會(huì)失效。

《JS高程3》:不一定非要同時(shí)指定getter和setter。只指定getter意味著屬性是不能寫(xiě),嘗試寫(xiě)入屬性會(huì)被忽略。在嚴(yán)格模式下,嘗試寫(xiě)入只指定了getter函數(shù)的的屬性會(huì)拋出錯(cuò)誤。類似地,沒(méi)有指定setter函數(shù)的屬性也不能讀,否則在非嚴(yán)格模式下會(huì)返回undefined,在嚴(yán)格模式下會(huì)拋出錯(cuò)誤。

    var obj = {_x:10};
    
    // 定義一個(gè)訪問(wèn)器屬性
    Object.defineProperty(obj,"x",{
        get:function () {
            return this._x
        }
    })
    // 讀取obj.x會(huì)隱式調(diào)用訪問(wèn)器屬性,返回obj._x的值(下劃線代表此屬性只能通過(guò)訪問(wèn)器讀寫(xiě))
    console.log(obj.x);            // 10
    
    // 嘗試為訪問(wèn)器屬性賦值
    // 直接賦值
    obj.x = "aaa";
    console.log(obj.x);            // 10     賦值失敗
    
    // 獲取obj.x的attributes
    var objxAttr = Object.getOwnPropertyDescriptor(obj,"x");
    for (var i in objxAttr) {
        document.write(
            i+" | "+objxAttr[i]+"
" ) } // get | function () { return this._x } // set | undefined // enumerable | false // configurable | false // 不可寫(xiě)的原因是value屬性與訪問(wèn)器屬性沖突,即(get、set)與value屬性沖突 // 可以通過(guò)查看attributes屬性,判斷屬性是否是訪問(wèn)器屬性還是數(shù)據(jù)屬性,存在set或者get的是訪問(wèn)器屬性

具體內(nèi)容請(qǐng)移步至相關(guān)知識(shí)點(diǎn)進(jìn)行更深入學(xué)習(xí),這里只介紹方法基礎(chǔ)用法

對(duì)象狀態(tài)相關(guān)方法 Object.preventExtensions()

如果一個(gè)對(duì)象可以添加新的屬性,則這個(gè)對(duì)象是可擴(kuò)展的。preventExtensions 可以讓這個(gè)對(duì)象變的不可擴(kuò)展,也就是不能再有新的屬性。需要注意的是不可擴(kuò)展的對(duì)象的屬性通常仍然可以被刪除。嘗試給一個(gè)不可擴(kuò)展對(duì)象添加新屬性的操作將會(huì)失敗,不過(guò)可能是靜默失敗,也可能會(huì)拋出 TypeError 異常(嚴(yán)格模式)。

Object.preventExtensions 只能阻止一個(gè)對(duì)象不能再添加新的自身屬性,仍然可以為該對(duì)象的原型添加屬性。然而Object.preventExtensions會(huì)阻止一個(gè)對(duì)象將__proto__屬性重新指向另一個(gè)對(duì)象。

    // Object.preventExtensions將原對(duì)象變的不可擴(kuò)展,并且返回原對(duì)象
    var obj = {};
    var obj2 = Object.preventExtensions(obj);
    alert(obj===obj2);            // true
    obj.x = "obj.x";
    alert(obj.x);                // undefined
    
    // 采用對(duì)象字面量定義的對(duì)象默認(rèn)可擴(kuò)展
    var o = {};
    alert(Object.isExtensible(o));            // true
    // 當(dāng)然,通過(guò)調(diào)用方法可以阻止
    Object.preventExtensions(o);
    alert(Object.isExtensible(o));            // false
    
    // 使用Object.defineProperty方法為一個(gè)不可擴(kuò)展的對(duì)象添加新屬性會(huì)拋出異常.
    var o2 = {a:"a"};
    Object.preventExtensions(o2);
    Object.defineProperty(o2,"b",{
        value:"test"            
    })
    // "Uncaught TypeError: Cannot define property:b, object is not extensible."
    
    
    // 一個(gè)不可擴(kuò)展對(duì)象的原型是不可更改的,__proto__是個(gè)非標(biāo)準(zhǔn)魔法屬性,可以更改一個(gè)對(duì)象的原型.
    var b = Object.preventExtensions({x:1,y:2});
    b.__proto__ = {a:10,b:20};            //  "Uncaught TypeError: # is not extensible" 

詳細(xì):MDN —— Object.preventExtensions()

Object.seal()

通常情況下,一個(gè)對(duì)象是可擴(kuò)展的(可以添加新的屬性)。密封一個(gè)對(duì)象會(huì)讓這個(gè)對(duì)象變的不能添加新屬性,且所有已有屬性會(huì)變的不可配置。屬性不可配置的效果就是屬性變的不可刪除,以及一個(gè)數(shù)據(jù)屬性不能被重新定義成為訪問(wèn)器屬性,或者反之。但屬性的值仍然可以修改。嘗試刪除一個(gè)密封對(duì)象的屬性或者將某個(gè)密封對(duì)象的屬性從數(shù)據(jù)屬性轉(zhuǎn)換成訪問(wèn)器屬性,結(jié)果會(huì)靜默失敗或拋出TypeError 異常(嚴(yán)格模式)。

不會(huì)影響從原型鏈上繼承的屬性。但 _proto_ ( ) 屬性的值也會(huì)不能修改。

    // 默認(rèn)可以修改屬性,添加屬性
    var obj = {
        a:"a",
        b:"b"
    };
    
    // 密封對(duì)象Object.seal(),注意方法會(huì)返回原對(duì)象
    obj = Object.seal(obj);
    console.log(Object.isSealed(obj));            // true
    
    // 依然可以修改屬性上的值
    obj.a = "Rewrite obj.a";
    obj.b = "Rewrite obj.b";
    console.log(obj.a+" | "+obj.b);                //  "Rewrite obj.a | Rewrite obj.b"
    
    // 但是除此之外的操作都無(wú)法完成
    obj.z = "obj.z";
    console.log(obj.z);                            // undefined 新屬性寫(xiě)入失敗
    console.log(delete obj.a);                    // false 刪除失敗
    
    // 無(wú)法定義訪問(wèn)器屬性
    Object.defineProperty(obj,"b",{                // "Uncaught TypeError: Cannot redefine property: b"
        get:function () {
            return this.b;
        }
    });
    // 方法也無(wú)法寫(xiě)入新屬性
    Object.defineProperty(obj,"z",{                // 拋出TypeError異常
        value:"obj.z"
    });
    console.log(obj.z);        // "Uncaught TypeError: Cannot define property:z, object is not extensible."
Object.freeze()

Object.freeze() 方法可以凍結(jié)一個(gè)對(duì)象,凍結(jié)指的是不能向這個(gè)對(duì)象添加新的屬性,不能修改其已有屬性的值,不能刪除已有屬性,以及不能修改該對(duì)象已有屬性的可枚舉性、可配置性、可寫(xiě)性。也就是說(shuō),這個(gè)對(duì)象永遠(yuǎn)是不可變的。該方法返回被凍結(jié)的對(duì)象。

    // 默認(rèn)可以修改屬性,添加屬性,刪除屬性等操作
    var obj = {
        a:"a",
        b:"b",
        o:{}
    };
    
    // 調(diào)用Object.freeze
    obj = Object.freeze(obj);
    
    // 現(xiàn)在任何對(duì)對(duì)象的操作都會(huì)失敗,嚴(yán)格模式下會(huì)TypeError異常
    console.log(delete obj.a);                // false
    
    obj.z = "obj.z";
    console.log(obj.z);                        // undefined
    
    // 但是非凍結(jié)對(duì)象依然可以修改,對(duì)象內(nèi)數(shù)組、對(duì)象等引用類型
    obj.o.fn = function () {console.log("yes")};
    obj.o.fn();                                // "yes"    添加成功
MDN提供了一個(gè)完全凍結(jié)對(duì)象的函數(shù):
    obj = {
      internal : {}
    };
    
    Object.freeze(obj);
    obj.internal.a = "aValue";
    
    obj.internal.a // "aValue"
    
    // 想讓一個(gè)對(duì)象變的完全凍結(jié),凍結(jié)所有對(duì)象中的對(duì)象,我們可以使用下面的函數(shù).
    
    function deepFreeze (o) {
      var prop, propKey;
      Object.freeze(o); // 首先凍結(jié)第一層對(duì)象.
      for (propKey in o) {
        prop = o[propKey];        
        if (!o.hasOwnProperty(propKey) || !(typeof prop === "object") || Object.isFrozen(prop)) {
        // 跳過(guò)原型鏈上的屬性和已凍結(jié)的對(duì)象.
          continue;
        }
    
        deepFreeze(prop); //遞歸調(diào)用.
      }
    }
    
    obj2 = {
      internal : {}
    };
    
    deepFreeze(obj2);
    obj2.internal.a = "anotherValue";
    obj2.internal.a; // undefined
Object.isExtensible()、Object.isSealed()、Object.isFrozen()

為對(duì)應(yīng)的檢測(cè)方法:

嚴(yán)格程度升序:preventExtensions —— seal —— freeze

鏈接:

MDN:Object.isExtensible()

MDN:Object.isSealed()

MDN:Object.isFrozen()

Object.isExtensible():

默認(rèn)情況下,對(duì)象是可擴(kuò)展的:即可以為他們添加新的屬性。以及它們的 proto 屬性可以被更改。Object.preventExtensions,Object.seal 或 Object.freeze 方法都可以標(biāo)記一個(gè)對(duì)象為不可擴(kuò)展(non-extensible)。

Object.isSealed()

    // 新建對(duì)象默認(rèn)不可密封
    var obj = {};
    console.log(Object.isSealed(obj));            // false
    
    // 如果是空對(duì)象變?yōu)椴豢蓴U(kuò)展preventExtensions,則對(duì)象也會(huì)變成密封對(duì)象
    obj = Object.preventExtensions(obj);
    console.log(
        Object.isExtensible(obj)+" | " +Object.isSealed(obj)
    )                                            // false | true        不可擴(kuò)展  | 密封
    
    // 但不是空對(duì)象,則不會(huì)發(fā)生上面情況,記住:密封對(duì)象與Configurable屬性相關(guān)聯(lián)
    var obj2 = {x:"obj2.x"};
    Object.preventExtensions(obj2);
    console.log(
        Object.isExtensible(obj2)+" | " +Object.isSealed(obj2)
    )                                            // false | false    不可擴(kuò)展  | 不密封
    
    // 反過(guò)來(lái)設(shè)置configurable設(shè)置為false,則自動(dòng)變?yōu)槊芊鈱?duì)象
    var o = {a:"o.a"};
    Object.preventExtensions(o);
    Object.defineProperty(o,"a",{
        configurable:false
    });
    console.log(
        Object.isSealed(o)
    );                                            // true
    
    // 直接生成一個(gè)密封對(duì)象
    var obj_seal = {};
    Object.seal(obj_seal);
    
    // 當(dāng)然密封對(duì)象也可以是凍結(jié)對(duì)象
    Object.isFrozen(obj_seal);                    // true
    var o2 = Object.seal({a:"o2.a"});
    console.log(Object.isFrozen(o2));            // false    依舊可更改o2.a屬性

Object.isFrozen()

一個(gè)對(duì)象是凍結(jié)的(frozen)是指它不可擴(kuò)展,所有屬性都是不可配置的(non-configurable),且所有數(shù)據(jù)屬性(data properties)都是不可寫(xiě)的(non-writable)

    // 一個(gè)對(duì)象默認(rèn)是可擴(kuò)展的,所以它也是非凍結(jié)的.
    assert(Object.isFrozen({}) === false);
    
    // 一個(gè)不可擴(kuò)展的空對(duì)象同時(shí)也是一個(gè)凍結(jié)對(duì)象.
    var vacuouslyFrozen = Object.preventExtensions({});
    assert(Object.isFrozen(vacuouslyFrozen) === true);
    
    // 一個(gè)非空對(duì)象默認(rèn)也是非凍結(jié)的.
    var oneProp = { p: 42 };
    assert(Object.isFrozen(oneProp) === false);
    
    // 讓這個(gè)對(duì)象變的不可擴(kuò)展,并不意味著這個(gè)對(duì)象變成了凍結(jié)對(duì)象,
    // 因?yàn)閜屬性仍然是可以配置的(而且可寫(xiě)的).
    Object.preventExtensions(oneProp);
    assert(Object.isFrozen(oneProp) === false);
    
    // ...如果刪除了這個(gè)屬性,則它會(huì)成為一個(gè)凍結(jié)對(duì)象.
    delete oneProp.p;
    assert(Object.isFrozen(oneProp) === true);
    
    // 一個(gè)不可擴(kuò)展的對(duì)象,擁有一個(gè)不可寫(xiě)但可配置的屬性,則它仍然是非凍結(jié)的.
    var nonWritable = { e: "plep" };
    Object.preventExtensions(nonWritable);
    Object.defineProperty(nonWritable, "e", { writable: false }); // 變得不可寫(xiě)
    assert(Object.isFrozen(nonWritable) === false);
    
    // 把這個(gè)屬性改為不可配置,會(huì)讓這個(gè)對(duì)象成為凍結(jié)對(duì)象.
    Object.defineProperty(nonWritable, "e", { configurable: false }); // 變得不可配置
    assert(Object.isFrozen(nonWritable) === true);
    
    // 一個(gè)不可擴(kuò)展的對(duì)象,擁有一個(gè)不可配置但可寫(xiě)的屬性,則它仍然是非凍結(jié)的.
    var nonConfigurable = { release: "the kraken!" };
    Object.preventExtensions(nonConfigurable);
    Object.defineProperty(nonConfigurable, "release", { configurable: false });
    assert(Object.isFrozen(nonConfigurable) === false);
    
    // 把這個(gè)屬性改為不可寫(xiě),會(huì)讓這個(gè)對(duì)象成為凍結(jié)對(duì)象.
    Object.defineProperty(nonConfigurable, "release", { writable: false });
    assert(Object.isFrozen(nonConfigurable) === true);
    
    // 一個(gè)不可擴(kuò)展的對(duì)象,值擁有一個(gè)訪問(wèn)器屬性,則它仍然是非凍結(jié)的.
    var accessor = { get food() { return "yum"; } };
    Object.preventExtensions(accessor);
    assert(Object.isFrozen(accessor) === false);
    
    // ...但把這個(gè)屬性改為不可配置,會(huì)讓這個(gè)對(duì)象成為凍結(jié)對(duì)象.
    Object.defineProperty(accessor, "food", { configurable: false });
    assert(Object.isFrozen(accessor) === true);
    
    // 使用Object.freeze是凍結(jié)一個(gè)對(duì)象最方便的方法.
    var frozen = { 1: 81 };
    assert(Object.isFrozen(frozen) === false);
    Object.freeze(frozen);
    assert(Object.isFrozen(frozen) === true);
    
    // 一個(gè)凍結(jié)對(duì)象也是一個(gè)密封對(duì)象.
    assert(Object.isSealed(frozen) === true);
    
    // 當(dāng)然,更是一個(gè)不可擴(kuò)展的對(duì)象.
    assert(Object.isExtensible(frozen) === false);        
Object.getPrototypeOf()

給定對(duì)象的原型。如果沒(méi)有繼承屬性,則返回 null 。

    var obj = {};
    console.log(Object.getPrototypeOf(obj) === Object.prototype);        // true

    var fn = function () {};
    console.log(Object.getPrototypeOf(fn) === Function.prototype);        // true
    
    var arr = [];
    console.log(Object.getPrototypeOf(arr) === Array.prototype);        // true
    
    var q = {x:"x"};
    var p = Object.create(q);
    console.log(Object.getPrototypeOf(p) === q);                        // true
    
    // 如果參數(shù)不是引用類型,將拋出異常
    var num = 123;
    Object.getPrototypeOf(num);
    // "Uncaught TypeError: Object.getPrototypeOf called on non-object"
Object實(shí)例方法 Object.prototype.valueOf()

JavaScript 調(diào)用 valueOf() 方法用來(lái)把對(duì)象轉(zhuǎn)換成原始類型的值(數(shù)值、字符串和布爾值)。 你很少需要自己調(diào)用此函數(shù);當(dāng)遇到一種需要轉(zhuǎn)換成一個(gè)原始值情況時(shí)候, JavaScript 會(huì)自動(dòng)調(diào)用此函數(shù)。

默認(rèn)情況下, valueOf() 會(huì)被每個(gè)對(duì)象Object繼承。每一個(gè)內(nèi)置對(duì)象都會(huì)覆蓋這個(gè)方法為了返回一個(gè)合理的值,如果對(duì)象沒(méi)有原始值,valueOf() 就會(huì)返回對(duì)象自身。

你可以在自己的代碼中使用 valueOf 方法用來(lái)把內(nèi)置對(duì)象的值轉(zhuǎn)換成原始值。 當(dāng)你創(chuàng)建了自定義對(duì)象時(shí),你可以覆蓋 Object.prototype.valueOf() 并調(diào)用來(lái)取代 Object 方法。

JavaScript的許多內(nèi)置對(duì)象都重寫(xiě)了該函數(shù),以實(shí)現(xiàn)更適合自身的功能需要。因此,不同類型對(duì)象的valueOf()方法的返回值和返回值類型均可能不同。

    // Array:返回?cái)?shù)組本身
    var arr = [1,2,3,"Array"];
    console.log(arr+" | "+(arr.valueOf() === arr));            //    "1,2,3,Array | true"    
    
    // String:返回當(dāng)前字符串
    var str = "string";
    console.log(str.valueOf() === str);                        // true
    
    // Number:返回當(dāng)前值
    var num = 123;
    console.log(num.valueOf() === num);                        // true
    
    // Boolean:返回當(dāng)前布爾值
    var boo = true;                                            // 布爾值
    console.log(boo.valueOf() === boo);                        // true
    // 這里是布爾對(duì)象
    var boo2 = new Boolean(false);                            // 布爾對(duì)象
    console.log(boo2.valueOf());                            // false
    console.log(typeof boo2.valueOf());                        // boolean
    // 注意:這里對(duì)布爾對(duì)象操作,返回的是原值的boolean類型,而不在是引用類型
    
    // Date:從1970年1月1日到現(xiàn)在的毫秒數(shù)
    var date = new Date();
    console.log(date.valueOf());                            // "1497789410938"
    
    // function: 返回當(dāng)前函數(shù)
    var fn = function () {console.log("fn")};
    (fn.valueOf())();                                        // fn
    
    // Object: 返回對(duì)象本身
    var obj = {x:"obj.a"};
    console.log(obj.valueOf() === obj);                        // true                            

當(dāng)然也可以覆蓋方法:

    var obj = {a:1};
    obj.valueOf = function () {return this.a}
    
    console.log(obj+1);            // 2
    // 這里隱式調(diào)用了valueOf方法
Object.prototype.toString()

每個(gè)對(duì)象都有一個(gè) toString() 方法,當(dāng)對(duì)象被表示為文本值時(shí)或者當(dāng)以期望字符串的方式引用對(duì)象時(shí),該方法被自動(dòng)調(diào)用。默認(rèn)情況下,toString() 方法被每個(gè)繼承自O(shè)bject的對(duì)象繼承。如果此方法在自定義對(duì)象中未被覆蓋,toString() 返回 "[object type]",其中type是對(duì)象類型。

    // toString返回對(duì)象的字符串形式,默認(rèn)情況下返回類型字符串
    var o1 = new Object();
    var o2 = {a:1};
    console.log(o1.toString());
    console.log(o2.toString());
    // "[object Object]"
    
    // 當(dāng)然可以自定義它
    var obj = {};
    obj.toString = function () {return 1}
    console.log(2+obj);                    // 3
關(guān)于toString()更詳細(xì)的可以看這里: 阮一峰 toString()的應(yīng)用:判斷數(shù)據(jù)類型 Object.prototype.toLocaleString()

Object"s toLocaleString 返回調(diào)用 toString() 方法的結(jié)果。

    var num = 123;
    console.log(num.toString() === num.toLocaleString());            // true
    
    var obj = {};
    console.log(obj.toString() === obj.toLocaleString());            // true
Object.prototype.hasOwnProperty()

所有繼承了 Object 的對(duì)象都會(huì)繼承到 hasOwnProperty 方法。這個(gè)方法可以用來(lái)檢測(cè)一個(gè)對(duì)象是否含有特定的自身屬性;和 in 運(yùn)算符不同,該方法會(huì)忽略掉那些從原型鏈上繼承到的屬性。

    // 判斷屬性書(shū)否存在
    var obj = {x:"obj.x"};        
    console.log(obj.hasOwnProperty("x"));            // true                
    delete obj.x;
    console.log(obj.hasOwnProperty("x"));            // false                
    
    // 判斷自身屬性還是繼承屬性
    var p = {z:10};
    var o = Object.create(p);
    o.a = 20;        
    console.log(o.hasOwnProperty("a")+" | "+o.hasOwnProperty("z"));                
    // true | false
    
    console.log(o.hasOwnProperty("toString"));            // false
    console.log(o.hasOwnProperty("hasOwnProperty"));    // false
    
    // 遍歷一個(gè)對(duì)象的自身屬性
    var o1 = {z:"o1.z"};
    var o2 = Object.create(o1);
    o2.x = "o2.x";
    o2.y = "o2.y";
    
    for (var i in o2) {
        if (o2.hasOwnProperty(i)) {
            console.log("自身屬性:"+i+" | "+"value:"+(o2[i]));
        } else {
            console.log(i+"不是自身屬性")
        }
    }
    // "自身屬性:x | value:o2.x"
    // "自身屬性:y | value:o2.y"
    // "z不是自身屬性"

hasOwnProperty也可以重寫(xiě),所以需要注意這一點(diǎn):

    var foo = {
        hasOwnProperty: function() {
            return false;
        },
        bar: "Here be dragons"
    };
    
    foo.hasOwnProperty("bar"); // 始終返回 false
    
    // 如果擔(dān)心這種情況,可以直接使用原型鏈上真正的 hasOwnProperty 方法
    ({}).hasOwnProperty.call(foo, "bar"); // true
    
    // 也可以使用 Object 原型上的 hasOwnProperty 屬性
    Object.prototype.hasOwnProperty.call(foo, "bar"); // true
    
Object.prototype.isPrototypeOf()

isPrototypeOf 方法允許你檢查一個(gè)對(duì)象是否存在于另一個(gè)對(duì)象的原型鏈上。

      function fn1() {
        this.a = "a";
    }
    function fn2() {
        this.b = "b";
    }
    
    fn2.prototype = new fn1();
    
    function fn3() {
        this.c = "c";
    }
    
    fn3.prototype = new fn2();
    
    function fn4() {
        this.d = "d";
    }
    
    fn4.prototype = new fn3();
    
    var test = new fn4();

    console.log(
        test.hasOwnProperty("a")+ " | "+test.hasOwnProperty("b")+" | "+test.hasOwnProperty("c")+" | "+test.hasOwnProperty("d")
    )
    // "false | false | false | true"
Object.prototype.propertyIsEnumerable()

每個(gè)對(duì)象都有 propertyIsEnumerable 方法。該方法可以判斷出指定對(duì)象里的屬性是否可枚舉,也就是說(shuō)該屬性是否可以通過(guò) for...in 循環(huán)等遍歷到,不過(guò)有些屬性雖然可以通過(guò) for...in 循環(huán)遍歷到,但因?yàn)樗鼈儾皇亲陨韺傩裕菑脑玩溕侠^承的屬性,所以該方法也會(huì)返回false。如果對(duì)象沒(méi)有指定的屬性,該方法返回 false。

MDN:Object.prototype.propertyIsEnumerable()

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/83512.html

相關(guān)文章

  • JavaScript標(biāo)準(zhǔn)庫(kù)系列——Object對(duì)象和Array對(duì)象(一)

    摘要:目錄導(dǎo)語(yǔ)對(duì)象對(duì)象小結(jié)導(dǎo)語(yǔ)本系列文章將重點(diǎn)講解提供的原生庫(kù)標(biāo)準(zhǔn)庫(kù),只要在支持語(yǔ)言的平臺(tái),標(biāo)準(zhǔn)庫(kù)中的提供的對(duì)象的屬性和方法都能使用對(duì)象對(duì)象的理解講的標(biāo)準(zhǔn)庫(kù),首先要從對(duì)象談起,因?yàn)橹蟮乃袑?duì)象都可以看做是對(duì)象構(gòu)造出來(lái)的因此,對(duì)象可以看做是一個(gè)構(gòu) 目錄 導(dǎo)語(yǔ) 1. Object對(duì)象 2. Array對(duì)象 3. 小結(jié) 導(dǎo)語(yǔ) 本系列文章將重點(diǎn)講解JavaScript提供的原生庫(kù)——標(biāo)準(zhǔn)庫(kù),只要...

    Scholer 評(píng)論0 收藏0
  • JavaScript標(biāo)準(zhǔn)庫(kù)系列——三大包裝對(duì)象(四)

    摘要:目錄導(dǎo)語(yǔ)包裝對(duì)象的理解三大包裝對(duì)象的知識(shí)點(diǎn)小結(jié)導(dǎo)語(yǔ)包裝對(duì)象是為了彌補(bǔ)基本數(shù)據(jù)類型的非對(duì)象特性而產(chǎn)生的,對(duì)于基本類型值而言,本來(lái)是不存在屬性和方法的,但是我們可以在使用字面量創(chuàng)建字符串時(shí),調(diào)用例如的方法,那么其內(nèi)在原理究竟是什么呢閱讀完本篇文 目錄 導(dǎo)語(yǔ) 1. 包裝對(duì)象的理解 2. 三大包裝對(duì)象的知識(shí)點(diǎn) 3. 小結(jié) 導(dǎo)語(yǔ) 包裝對(duì)象是為了彌補(bǔ)基本數(shù)據(jù)類型的非對(duì)象特性而產(chǎn)生的,對(duì)于基本類型...

    sean 評(píng)論0 收藏0
  • 什么是 JAVASCRIPT?

    摘要:,微軟發(fā)布,同時(shí)發(fā)布了,該語(yǔ)言模仿同年發(fā)布的。,公司在瀏覽器對(duì)抗中沒(méi)落,將提交給國(guó)際標(biāo)準(zhǔn)化組織,希望能夠成為國(guó)際標(biāo)準(zhǔn),以此抵抗微軟。同時(shí)將標(biāo)準(zhǔn)的設(shè)想定名為和兩類。,尤雨溪發(fā)布項(xiàng)目。,正式發(fā)布,并且更名為。,發(fā)布,模塊系統(tǒng)得到廣泛的使用。 前言 作為程序員,技術(shù)的落實(shí)與鞏固是必要的,因此想到寫(xiě)個(gè)系列,名為 why what or how 每篇文章試圖解釋清楚一個(gè)問(wèn)題。 這次的 why w...

    ephererid 評(píng)論0 收藏0
  • 001-讀書(shū)筆記-JavaScript高級(jí)程序設(shè)計(jì) JavaScript簡(jiǎn)介

    摘要:由于計(jì)算機(jī)的國(guó)際化,組織的標(biāo)準(zhǔn)牽涉到很多其他國(guó)家,因此組織決定改名表明其國(guó)際性。規(guī)范由萬(wàn)維網(wǎng)聯(lián)盟制定。級(jí)標(biāo)準(zhǔn)級(jí)標(biāo)準(zhǔn)是不存在的,級(jí)一般指的是最初支持的。 這篇筆記的內(nèi)容對(duì)應(yīng)的是《JavaScript高級(jí)程序設(shè)計(jì)(第三版)》中的第一章。 1.ECMA 和 ECMA-262 ECMA 是歐洲計(jì)算機(jī)制造商協(xié)會(huì)的縮寫(xiě),全程是 European Computer Manufacturers Ass...

    masturbator 評(píng)論0 收藏0
  • JavaScript 原型系統(tǒng)的變遷,以及 ES6 class

    摘要:一般我們對(duì)這種構(gòu)造函數(shù)命名都會(huì)采用,并把它稱呼為類,這不僅是為了跟的理念保持一致,也是因?yàn)榈膬?nèi)建類也是這種命名。由生成的對(duì)象,其是。這是標(biāo)準(zhǔn)的規(guī)定。本文的主題是原型系統(tǒng)的變遷,所以并沒(méi)有涉及和對(duì)原型鏈的影響。 概述 JavaScript 的原型系統(tǒng)是最初就有的語(yǔ)言設(shè)計(jì)。但隨著 ES 標(biāo)準(zhǔn)的進(jìn)化和新特性的添加。它也一直在不停進(jìn)化。這篇文章的目的就是梳理一下早期到 ES5 和現(xiàn)在 ES6,...

    chuyao 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<