成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JavaScript中的Object.defineProperty()和defineProperti

sanyang / 1043人閱讀

摘要:語(yǔ)法將要被添加屬性或修改屬性的對(duì)象該對(duì)象的一個(gè)或多個(gè)鍵值對(duì)定義了將要為對(duì)象添加或修改的屬性的具體配置張三張三功能該方法返回指定對(duì)象上一個(gè)自有屬性對(duì)應(yīng)的屬性描述符。

文章同步到github

ECMAS-262第5版在定義只有內(nèi)部采用的特性時(shí),提供了描述了屬性特征的幾種屬性。ECMAScript對(duì)象中目前存在的屬性描述符主要有兩種,數(shù)據(jù)描述符(數(shù)據(jù)屬性)和存取描述符(訪問(wèn)器屬性),數(shù)據(jù)描述符是一個(gè)擁有可寫(xiě)或不可寫(xiě)值的屬性。存取描述符是由一對(duì) getter-setter 函數(shù)功能來(lái)描述的屬性。

Object的definePropertydefineProperties這兩個(gè)方法在js中的重要性十分重要,主要功能就是用來(lái)定義或修改這些內(nèi)部屬性,與之相對(duì)應(yīng)的getOwnPropertyDescriptorgetOwnPropertyDescriptors就是獲取這行內(nèi)部屬性的描述。

下面文章我先介紹數(shù)據(jù)描述符和存取描述符的屬性代表的含義,然后簡(jiǎn)單介紹以上四個(gè)方法的基本功能,這些如果了解可直接跳過(guò),最后我會(huì)舉例擴(kuò)展及說(shuō)明各內(nèi)部屬性在各種場(chǎng)景下產(chǎn)生的實(shí)際效果,那才是這篇文章的核心內(nèi)容。本文章關(guān)于概念性的描述還是會(huì)盡量使用《javaScript高級(jí)教程》、MDN網(wǎng)站等概念,保證準(zhǔn)確和易于大家理解,講解部分則結(jié)合個(gè)人理解和舉例說(shuō)明。

數(shù)據(jù)(數(shù)據(jù)描述符)屬性

數(shù)據(jù)屬性有4個(gè)描述內(nèi)部屬性的特性

[[Configurable]]

表示能否通過(guò)delete刪除此屬性,能否修改屬性的特性,或能否修改把屬性修改為訪問(wèn)器屬性,如果直接使用字面量定義對(duì)象,默認(rèn)值為true

[[Enumerable]]

表示該屬性是否可枚舉,即是否通過(guò)for-in循環(huán)或Object.keys()返回屬性,如果直接使用字面量定義對(duì)象,默認(rèn)值為true

[[Writable]]

能否修改屬性的值,如果直接使用字面量定義對(duì)象,默認(rèn)值為true

[[Value]]

該屬性對(duì)應(yīng)的值,默認(rèn)為undefined

訪問(wèn)器(存取描述符)屬性

訪問(wèn)器屬性也有4個(gè)描述內(nèi)部屬性的特性

[[Configurable]]

和數(shù)據(jù)屬性的[[Configurable]]一樣,表示能否通過(guò)delete刪除此屬性,能否修改屬性的特性,或能否修改把屬性修改為訪問(wèn)器屬性,如果直接使用字面量定義對(duì)象,默認(rèn)值為true

[[Enumerable]]

和數(shù)據(jù)屬性的[[Configurable]]一樣,表示該屬性是否可枚舉,即是否通過(guò)for-in循環(huán)或Object.keys()返回屬性,如果直接使用字面量定義對(duì)象,默認(rèn)值為true

[[Get]]

一個(gè)給屬性提供 getter 的方法(訪問(wèn)對(duì)象屬性時(shí)調(diào)用的函數(shù),返回值就是當(dāng)前屬性的值),如果沒(méi)有 getter 則為 undefined。該方法返回值被用作屬性值。默認(rèn)為 undefined

[[Set]]

一個(gè)給屬性提供 setter 的方法(給對(duì)象屬性設(shè)置值時(shí)調(diào)用的函數(shù)),如果沒(méi)有 setter 則為 undefined。該方法將接受唯一參數(shù),并將該參數(shù)的新值分配給該屬性。默認(rèn)為 undefined

創(chuàng)建/修改/獲取屬性的方法 Object.defineProperty()

功能:
方法會(huì)直接在一個(gè)對(duì)象上定義一個(gè)新屬性,或者修改一個(gè)對(duì)象的現(xiàn)有屬性, 并返回這個(gè)對(duì)象。如果不指定configurable, writable, enumerable ,則這些屬性默認(rèn)值為false,如果不指定value, get, set,則這些屬性默認(rèn)值為undefined

語(yǔ)法: Object.defineProperty(obj, prop, descriptor)

obj: 需要被操作的目標(biāo)對(duì)象
prop: 目標(biāo)對(duì)象需要定義或修改的屬性的名稱
descriptor: 將被定義或修改的屬性的描述符

var obj = new Object();

Object.defineProperty(obj, "name", {
    configurable: false,
    writable: true,
    enumerable: true,
    value: "張三"
})

console.log(obj.name)  //張三
Object.defineProperties()

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

語(yǔ)法: Object.defineProperties(obj, props)

obj: 將要被添加屬性或修改屬性的對(duì)象
props: 該對(duì)象的一個(gè)或多個(gè)鍵值對(duì)定義了將要為對(duì)象添加或修改的屬性的具體配置

var obj = new Object();
Object.defineProperties(obj, {
    name: {
        value: "張三",
        configurable: false,
        writable: true,
        enumerable: true
    },
    age: {
        value: 18,
        configurable: true
    }
})

console.log(obj.name, obj.age) // 張三, 18
Object.getOwnPropertyDescriptor()

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

語(yǔ)法: Object.getOwnPropertyDescriptor(obj, prop)

obj: 需要查找的目標(biāo)對(duì)象
prop: 目標(biāo)對(duì)象內(nèi)屬性名稱

var person = {
    name: "張三",
    age: 18
}

var desc = Object.getOwnPropertyDescriptor(person, "name"); 
console.log(desc)  結(jié)果如下
// {
//     configurable: true,
//     enumerable: true,
//     writable: true,
//     value: "張三"
// }
Object. getOwnPropertyDescriptors()

功能:
所指定對(duì)象的所有自身屬性的描述符,如果沒(méi)有任何自身屬性,則返回空對(duì)象。

語(yǔ)法: Object.getOwnPropertyDescriptors(obj)

obj: 需要查找的目標(biāo)對(duì)象

var person = {
    name: "張三",
    age: 18
}
var desc = Object.getOwnPropertyDescriptors(person, "name");
console.log(desc) 
//{
//    configurable: true,
//    enumerable: true,
//    value: "張三",
//    writable: true
//}
各種場(chǎng)景下描述符屬性的的擴(kuò)展示例講解 . configurable

如果設(shè)置configurable屬性為false,則不可使用delete操作符(在嚴(yán)格模式下拋出錯(cuò)誤), 修改所有內(nèi)部屬性值會(huì)拋出錯(cuò)誤,在《javaScript高級(jí)教程中》說(shuō)只可以改變writable的值,現(xiàn)在改變writable的值也會(huì)拋出錯(cuò)誤

在對(duì)象中添加一個(gè)數(shù)據(jù)描述符屬性
var person = {};

Object.defineProperty(person, "name", {
    configurable: false,
    value: "John"
}) ;

delete person.name   // 嚴(yán)格模式下拋出錯(cuò)誤

console.log(person.name)  // "John"  沒(méi)有刪除

Object.defineProperty(person, "name", {
    configurable: true  //報(bào)錯(cuò)
});

Object.defineProperty(person, "name", {
    enumerable: 2  //報(bào)錯(cuò)
});

Object.defineProperty(person, "name", {
    writable: true  //報(bào)錯(cuò)
});

Object.defineProperty(person, "name", {
    value: 2  //報(bào)錯(cuò)
});

注意:
以上是最開(kāi)始定義屬性描述符時(shí),writabl默認(rèn)為false,才會(huì)出現(xiàn)上述效果,如果writable定義為true, 則可以修改[[writable]]和[[value]]屬性值,修改另外兩個(gè)屬性值報(bào)錯(cuò)

var obj = {};

Object.defineProperty(obj, "a", {
    configurable: false,
    writable: true,
    value: 1
});

Object.defineProperty(obj, "a", {
    // configurable: true, //報(bào)錯(cuò)
    // enumerable: true,  //報(bào)錯(cuò)
    writable: false,
    value: 2
});
var d = Object.getOwnPropertyDescriptor(obj, "a")
console.log(d);
// {
//     value: 2, 
//     writable: false, 
// }
在對(duì)象中添加存取描述符屬性
var obj = {};
var aValue; //如果不初始化變量, 不給下面的a屬性設(shè)置值,直接讀取會(huì)報(bào)錯(cuò)aValue is not defined
var b;
Object.defineProperty(obj, "a", {
    configurable : true,
    enumerable : true,
    get: function() {
        return aValue
    },
    set: function(newValue) {
        aValue = newValue;
        b = newValue + 1
    }
})
console.log(b) // undefined
console.log(obj.a)  // undefined, 當(dāng)讀取屬性值時(shí),調(diào)用get方法,返回undefined
obj.a = 2;  // 當(dāng)設(shè)置屬性值時(shí),調(diào)用set方法,aValue為2

console.log(obj.a) // 2  讀取屬性值,調(diào)用get方法,此時(shí)aValue為2
console.log(b) // 3  再給obj.a賦值時(shí),執(zhí)行set方法,b的值被修改為2,額外說(shuō)一句,vue中的計(jì)算屬性就是利用setter來(lái)實(shí)現(xiàn)的

注意:
1.getter和setter可以不同時(shí)使用,但在嚴(yán)格模式下只其中一個(gè),會(huì)拋出錯(cuò)誤
2.數(shù)據(jù)描述符與存取描述符不可混用,會(huì)拋出錯(cuò)誤

var obj = {};
Object.defineProperty(obj, "a", {
    value: "a1",
    get: function() {
       return "a2"
    }    
});

3.全局環(huán)境下:

var a = 1;  // a屬于window, 相當(dāng)于window.a

讓我們來(lái)看看a的描述符屬性

var d = Object.getOwnPropertyDescriptor(window, "a");
console.log(d)
// {
//     configurable: false,
//     value: 1,
//     writable: true,
//     enumerable: true
// }

在來(lái)看一下另一種不適用var聲明的方式初始化a變量

a = 1; //a相當(dāng)于window的一個(gè)屬性, window.a

再來(lái)看看此時(shí)a的描述符屬性

var d = Object.getOwnPropertyDescriptor(window, "a");
console.log(d)
// {
//     configurable: true,   // 此時(shí)configurable屬性值為true
//     value: 1,
//     writable: true,
//     enumerable: true
// }

注意:

只有使用var, let等操作符才是定義變量,而不使用var,直接a=1;,這樣a的含義為window的一個(gè)屬性,并不是我們所說(shuō)的變量的概念。使用 var定義的任何變量,其configurable屬性值都為false,定義對(duì)象也是一樣

var b = {
    name: "bbb"
}
var d = Object.getOwnPropertyDescriptor(window, "b");
console.log(d)
// {
//     configurable: false
//     value: 1,
//     writable: true,
//     enumerable: true
// }

但是這里需要說(shuō)明的一點(diǎn)是,使用字面量定義的對(duì)象,該對(duì)象內(nèi)部的屬性的數(shù)據(jù)描述符屬性都為true

var b = {
    name: "bbb"
}
var d = Object.getOwnPropertyDescriptor(b, "name");
console.log(d)
// {
//     configurable: true
//     writable: true,
//     enumerable: true
//     value: "bbb"
// }
Writable

當(dāng)writable為false(并且configurable為true),[[value]]可以通過(guò)defineeProperty修改, 但不能直接賦值修改

var obj = {};

Object.defineProperty(obj, "a", {
    configurable: true,
    enumerable: false,
    writable: false,
    value: 1
});

Object.defineProperty(obj, "a", {
    configurable: false,
    enumerable: true,
    writable: false ,
    value: 2
});
var d = Object.getOwnPropertyDescriptor(obj, "a")

console.log(d); // 結(jié)果如下
// {
//     value: 2, 
//     writable: false, 
//     enumerable: true, 
//     configurable: false
// }


但是如果直接復(fù)制修改
var obj = {}

Object.defineProperty(obj, "a", {
    configurable: true,
    enumerable: false,
    writable: false,
    value: 1
});
obj.a=2;
var d = Object.getOwnPropertyDescriptor(obj, "a")

console.log(d); // 結(jié)果如下

// {
//     value: 1,  // 沒(méi)有做出修改
//     writable: false, 
//     enumerable: true, 
//     configurable: false
// }
Enumerable

直接上例子

var obj = {};
Object.defineProperties(obj, {
    a: {
        value: 1,
        enumerable: false
    }, 
    b: {
        value: 2,
        enumerable: true
    },
    c: {
        value: 3,
        enumerable: false
    }
})

obj.d = 4;

//等同于

//Object.defineProperty(obj, "d", {
//    configurable: true,
//    enumerable: true,
//    writable: true,
//    value: 4
//})

for(var key in obj) {
    console.log(key);  
    // 打印一次b, 一次d, a和c屬性enumerable為false,不可被枚舉
} 

var arr = Object.keys(obj);
console.log(arr);  // ["b", "d"]
get和set 簡(jiǎn)易的數(shù)據(jù)雙向綁定

在線demo地址: http://www.sunzhaoye.com/demo...

html代碼:


    

input1=>

input2=>

我每次比input1的值加1=>

js代碼:

var oInput1 = document.getElementById("input1");
var oInput2 = document.getElementById("input2");
var oSpan = document.getElementById("span");
var obj = {};
Object.defineProperties(obj, {
    val1: {
        configurable: true,
        get: function() {
            oInput1.value = 0;
            oInput2.value = 0;
            oSpan.innerHTML = 0;
            return 0
        },
        set: function(newValue) {
            oInput2.value = newValue;
            oSpan.innerHTML = Number(newValue) ? Number(newValue) : 0
        }
    },
    val2: {
        configurable: true,
        get: function() {
            oInput1.value = 0;
            oInput2.value = 0;
            oSpan.innerHTML = 0;
            return 0
        },
        set: function(newValue) {
            oInput1.value = newValue;
            oSpan.innerHTML = Number(newValue)+1;
        }
    }
})
oInput1.value = obj.val1;
oInput1.addEventListener("keyup", function() {
    obj.val1 = oInput1.value;
}, false)
oInput2.addEventListener("keyup", function() {
    obj.val2 = oInput2.value;
}, false)
總結(jié)

終于到了最后了,就不具體梳理總結(jié)了。雖然我們?cè)陂_(kāi)過(guò)過(guò)程中不怎么使用幾種方法,但理解之后對(duì)于我們理解js中對(duì)象有很大幫助,對(duì)后續(xù)進(jìn)步也很有幫助,比如vue的實(shí)現(xiàn)原理等。個(gè)人能力有限,還希望大家發(fā)現(xiàn)問(wèn)題后能多多指點(diǎn),共同進(jìn)步。

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

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

相關(guān)文章

  • 詳解JavaScript之神奇的Object.defineProperty

    摘要:與當(dāng)與同時(shí)為時(shí),屬性不能重新使用定義,嚴(yán)格模式下會(huì)報(bào)錯(cuò)示例云麒報(bào)錯(cuò)當(dāng)或者為時(shí),屬性可以重新使用定義,這一點(diǎn)讀者不妨自行測(cè)試。 摘要: JavaScript有個(gè)很神奇的Object.defineProperty(),了解一下? =與Object.defineProperty 為JavaScript對(duì)象新增或者修改屬性,有兩種不同方式:直接使用=賦值或者使用Object.definePro...

    baishancloud 評(píng)論0 收藏0
  • JavaScript深入理解對(duì)象方法——Object.defineProperty()

    摘要:返回值被傳遞給函數(shù)的對(duì)象。描述該方法允許精確添加或修改對(duì)象的屬性。描述符必須是兩種形式之一不能同時(shí)是兩者。可以是任何有效的值數(shù)值,對(duì)象,函數(shù)等。該方法返回值被用作屬性值。該方法將接受唯一參數(shù),并將該參數(shù)的新值分配給該屬性。 Object.defineProperties() Object.defineProperty() 方法會(huì)直接在一個(gè)對(duì)象上定義一個(gè)新屬性,或者修改一個(gè)對(duì)象的現(xiàn)有屬性...

    woshicixide 評(píng)論0 收藏0
  • javascript高級(jí)程序設(shè)計(jì)》筆記:對(duì)象數(shù)據(jù)屬性訪問(wèn)器屬性

    摘要:枚舉對(duì)象的屬性第二種情況設(shè)置為,可以被枚舉。內(nèi)置對(duì)象訪問(wèn)器屬性方法介紹摘自方法返回指定對(duì)象上一個(gè)自有屬性對(duì)應(yīng)的屬性描述符。對(duì)象中存在的屬性描述符主要有數(shù)據(jù)描述符和訪問(wèn)器描述符兩種返回傳遞給函數(shù)的對(duì)象參考中的 1. 什么是對(duì)象 對(duì)象是無(wú)序?qū)傩缘募?創(chuàng)建自定義對(duì)象最簡(jiǎn)單的方式就是以字面量的形式創(chuàng)建對(duì)象(或創(chuàng)建一個(gè)Object實(shí)例),然后再為它添加屬性和方法,如下所示: var perso...

    mating 評(píng)論0 收藏0
  • 深入理解JavaScript中的屬性特性

    摘要:深入理解中的屬性和特性中屬性和特性是完全不同的兩個(gè)概念,這里我將根據(jù)自己所學(xué),來(lái)深入理解中的屬性和特性。其中第三個(gè)參數(shù)描述符對(duì)象是對(duì)象字面量的方法創(chuàng)建的,里面的屬性和屬性值實(shí)際上保存的是要修改的特性和特性值。 深入理解JavaScript中的屬性和特性   JavaScript中屬性和特性是完全不同的兩個(gè)概念,這里我將根據(jù)自己所學(xué),來(lái)深入理解JavaScript中的屬性和特性。   主...

    VPointer 評(píng)論0 收藏0
  • JavaScriptObject.defineProperty 的使用

    摘要:一旦目標(biāo)對(duì)象訪問(wèn)該屬性,就會(huì)調(diào)用這個(gè)方法,并返回結(jié)果。如果為,則任何嘗試刪除目標(biāo)屬性或修改屬性以下特性的行為將被無(wú)效化,默認(rèn)為。語(yǔ)法參數(shù)目標(biāo)對(duì)象要為目標(biāo)對(duì)象添加的屬性,其中和分別代表中的第二和第三個(gè)參數(shù)。 Object.defineProperty The Object.defineProperty() method defines a new property directly on...

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

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

0條評(píng)論

閱讀需要支付1元查看
<