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

資訊專欄INFORMATION COLUMN

標(biāo)準(zhǔn)庫(二)屬性描述對(duì)象

468122151 / 1077人閱讀

摘要:也就是說,屬性控制了屬性描述對(duì)象的可寫性??杀闅v性返回一個(gè)布爾值,表示目標(biāo)屬性是否可遍歷運(yùn)算符不管某個(gè)屬性是對(duì)象自身的還是繼承的,都會(huì)返回。上面的寫法與定義屬性描述對(duì)象是等價(jià)的,而且使用更廣泛。

屬性描述對(duì)象

概述
Object.getOwnPropertyDescriptor()
Object.getOwnPropertyNames()
Object.defineProperty(),Object.defineProperties()
Object.prototype.propertyIsEnumerable()
元屬性
value
writable
enumerable
configurable
存取器
對(duì)象的拷貝
控制對(duì)象狀態(tài)
Object.preventExtensions()
Object.isExtensible()
Object.seal()
Object.isSealed()
Object.freeze()
Object.isFrozen()
局限性

1.概述
每個(gè)屬性都有自己對(duì)應(yīng)的屬性描述對(duì)象,保存該屬性的一些元信息
{
value: 123,
writable: false,
enumerable: true,
configurable: false,
get: undefined,
set: undefined
}
屬性描述對(duì)象提供6個(gè)元屬性。

(1)value

value是該屬性的屬性值,默認(rèn)為undefined。

(2)writable

writable是一個(gè)布爾值,表示屬性值(value)是否可改變(即是否可寫),默認(rèn)為true。

(3)enumerable

enumerable是一個(gè)布爾值,表示該屬性是否可遍歷,默認(rèn)為true。如果設(shè)為false,會(huì)使得某些操作(比如for...in循環(huán)、Object.keys())跳過該屬性。

(4)configurable

configurable是一個(gè)布爾值,表示可配置性,默認(rèn)為true。如果設(shè)為false,將阻止某些操作改寫該屬性,比如無法刪除該屬性,也不得改變該屬性的屬性描述對(duì)象(value屬性除外)。也就是說,configurable屬性控制了屬性描述對(duì)象的可寫性。

(5)get

get是一個(gè)函數(shù),表示該屬性的取值函數(shù)(getter),默認(rèn)為undefined。

(6)set

set是一個(gè)函數(shù),表示該屬性的存值函數(shù)(setter),默認(rèn)為undefined。

2.Object.getOwnPropertyDescriptor()
Object.getOwnPropertyDescriptor()方法可以獲取屬性描述對(duì)象。它的第一個(gè)參數(shù)是目標(biāo)對(duì)象,第二個(gè)參數(shù)是一個(gè)字符串,對(duì)應(yīng)目標(biāo)對(duì)象的某個(gè)屬性名。

Object.getOwnPropertyDescriptor()方法只能用于對(duì)象自身的屬性,不能用于繼承的屬性。

var obj = { p: "a" };

Object.getOwnPropertyDescriptor(obj, "toString")
// undefined
上面代碼中,toString是obj對(duì)象繼承的屬性,Object.getOwnPropertyDescriptor()無法獲取。

3.Object.getOwnPropertyNames()
Object.keys([]) // []
Object.getOwnPropertyNames([]) // [ "length" ]

Object.keys(Object.prototype) // []
Object.getOwnPropertyNames(Object.prototype)
// ["hasOwnProperty",
// "valueOf",
// "constructor",
// "toLocaleString",
// "isPrototypeOf",
// "propertyIsEnumerable",
// "toString"]
上面代碼中,數(shù)組自身的length屬性是不可遍歷的,Object.keys不會(huì)返回該屬性。第二個(gè)例子的Object.prototype也是一個(gè)對(duì)象,所有實(shí)例對(duì)象都會(huì)繼承它,它自身的屬性都是不可遍歷的。

4.Object.defineProperty(),
Object.defineProperty方法接受三個(gè)參數(shù),依次如下。

object:屬性所在的對(duì)象
propertyName:字符串,表示屬性名
attributesObject:屬性描述對(duì)象

4.1Object.defineProperties()
var obj = {};

Object.defineProperty(obj, "p", {
value: 123,
get: function() { return 456; }
});
// TypeError: Invalid property.
// A property cannot both have accessors and be writable or have a value

Object.defineProperty(obj, "p", {
writable: true,
get: function() { return 456; }
});
// TypeError: Invalid property descriptor.
// Cannot both specify accessors and a value or writable attribute
4.1.2writable、configurable、enumerable這三個(gè)屬性的默認(rèn)值都為false
4.1.1注意,一旦定義了取值函數(shù)get(或存值函數(shù)set),就不能將writable屬性設(shè)為true,或者同時(shí)定義value屬性,否則會(huì)報(bào)錯(cuò)。

5.Object.prototype.propertyIsEnumerable()
這個(gè)方法只能用于判斷對(duì)象自身的屬性,對(duì)于繼承的屬性一律返回false
var obj = {};
obj.p = 123;

obj.propertyIsEnumerable("p") // true
obj.propertyIsEnumerable("toString") // false
上面代碼中,obj.p是可遍歷的,而obj.toString是繼承的屬性

6.元屬性
6.1value
value屬性是目標(biāo)屬性的值。

var obj = {};
obj.p = 123;

Object.getOwnPropertyDescriptor(obj, "p").value
// 123

Object.defineProperty(obj, "p", { value: 246 });
obj.p // 246
上面代碼是通過value屬性,讀取或改寫obj.p的例子

6.2
writable屬性是一個(gè)布爾值,決定了目標(biāo)屬性的值(value)是否可以被改變
6.2.1如果原型對(duì)象的某個(gè)屬性的writable為false,那么子對(duì)象將無法自定義這個(gè)屬性。

var proto = Object.defineProperty({}, "foo", {
value: "a",
writable: false
});

var obj = Object.create(proto);

obj.foo = "b";
obj.foo // "a"
上面代碼中,proto是原型對(duì)象,它的foo屬性不可寫。obj對(duì)象繼承proto,也不可以再自定義這個(gè)屬性了。如果是嚴(yán)格模式,這樣做還會(huì)拋出一個(gè)錯(cuò)誤。

6.3enumerable
6.3.1enumerable(可遍歷性)返回一個(gè)布爾值,表示目標(biāo)屬性是否可遍歷

6.3.2in運(yùn)算符不管某個(gè)屬性是對(duì)象自身的還是繼承的,都會(huì)返回true。

后來就引入了“可遍歷性”這個(gè)概念。只有可遍歷的屬性,才會(huì)被for...in循環(huán)遍歷,同時(shí)還規(guī)定toString這一類實(shí)例對(duì)象繼承的原生屬性,都是不可遍歷的,這樣就保證了for...in循環(huán)的可用性。

6.3.3具體來說,如果一個(gè)屬性的enumerable為false,下面三個(gè)操作不會(huì)取到該屬性。

for..in循環(huán)
Object.keys方法
JSON.stringify方法
object.getpropertynames都可以遍歷。

6.3.4用于保密屬性
JSON.stringify方法會(huì)排除enumerable為false的屬性,有時(shí)可以利用這一點(diǎn)。如果對(duì)象的 JSON 格式輸出要排除某些屬性,就可以把這些屬性的enumerable設(shè)為false。

6.4configurable
onfigurable為false時(shí),value、writable、enumerable和configurable都不能被修改了

var obj = Object.defineProperty({}, "p", {
value: 1,
writable: false,
enumerable: false,
configurable: false
});

Object.defineProperty(obj, "p", {value: 2})
// TypeError: Cannot redefine property: p

Object.defineProperty(obj, "p", {writable: true})
// TypeError: Cannot redefine property: p

Object.defineProperty(obj, "p", {enumerable: true})
// TypeError: Cannot redefine property: p

Object.defineProperty(obj, "p", {configurable: true})
// TypeError: Cannot redefine property: p
上面代碼中,obj.p的configurable為false。然后,改動(dòng)value、writable、enumerable、configurable,結(jié)果都報(bào)錯(cuò)。

6.4.1注意,writable只有在false改為true會(huì)報(bào)錯(cuò),true改為false是允許的

6.4.2至于value,只要writable和configurable有一個(gè)為true,就允許改動(dòng)

6.4.3可配置性決定了目標(biāo)屬性是否可以被刪除(delete)

6.5存取器
var obj = Object.defineProperty({}, "p", {
get: function () {

return "getter";

},
set: function (value) {

console.log("setter: " + value);

}
});

obj.p // "getter"
obj.p = 123 // "setter: 123"
上面代碼中,obj.p定義了get和set屬性。obj.p取值時(shí),就會(huì)調(diào)用get;賦值時(shí),就會(huì)調(diào)用set。

JavaScript 還提供了存取器的另一種寫法。

var obj = {
get p() {

return "getter";

},
set p(value) {

console.log("setter: " + value);

}
};
上面的寫法與定義屬性描述對(duì)象是等價(jià)的,而且使用更廣泛。

6.5.1應(yīng)用
存取器往往用于,屬性的值依賴對(duì)象內(nèi)部數(shù)據(jù)的場合。

var obj ={
$n : 5,
get next() { return this.$n++ },
set next(n) {

if (n >= this.$n) this.$n = n;
else throw new Error("新的值必須大于當(dāng)前值");

}
};

obj.next // 5

obj.next = 10;
obj.next // 10

obj.next = 5;
// Uncaught Error: 新的值必須大于當(dāng)前值
上面代碼中,next屬性的存值函數(shù)和取值函數(shù),都依賴于內(nèi)部屬性$n。

7.對(duì)象的拷貝
var extend = function (to, from) {
for (var property in from) {

to[property] = from[property];

}

return to;
}

extend({}, {
a: 1
})
// {a: 1}
7.1上面這個(gè)方法的問題在于,如果遇到存取器定義的屬性,會(huì)只拷貝值。
extend({}, {
get a() { return 1 }
})
// {a: 1}
為了解決這個(gè)問題,我們可以通過Object.defineProperty方法來拷貝屬性。

var extend = function (to, from) {
for (var property in from) {

if (!from.hasOwnProperty(property)) continue;
Object.defineProperty(
  to,
  property,
  Object.getOwnPropertyDescriptor(from, property)
);

}

return to;
}

extend({}, { get a(){ return 1 } })
// { get a(){ return 1 } })
上面代碼中,hasOwnProperty那一行用來過濾掉繼承的屬性,否則可能會(huì)報(bào)錯(cuò),因?yàn)镺bject.getOwnPropertyDescriptor讀不到繼承屬性的屬性描述對(duì)象。
8.控制對(duì)象狀態(tài)
有時(shí)需要凍結(jié)對(duì)象的讀寫狀態(tài),防止對(duì)象被改變。JavaScript 提供了三種凍結(jié)方法,最弱的一種是Object.preventExtensions,其次是Object.seal,最強(qiáng)的是Object.freeze

8.1Object.preventExtensions()
無法增加屬性
var obj = new Object();
Object.preventExtensions(obj);

Object.defineProperty(obj, "p", {
value: "hello"
});
// TypeError: Cannot define property:p, object is not extensible.

obj.p = 1;
obj.p // undefined

Object.isExtensible()
8.2Object.seal()
無法增刪屬性
8.2.1Object.seal實(shí)質(zhì)是把屬性描述對(duì)象的configurable屬性設(shè)為false,因此屬性描述對(duì)象不再能改變了
var obj = {
p: "a"
};

// seal方法之前
Object.getOwnPropertyDescriptor(obj, "p")
// Object {
// value: "a",
// writable: true,
// enumerable: true,
// configurable: true
// }

Object.seal(obj);

// seal方法之后
Object.getOwnPropertyDescriptor(obj, "p")
// Object {
// value: "a",
// writable: true,
// enumerable: true,
// configurable: false
// }

Object.defineProperty(o, "p", {
enumerable: false
})
// TypeError: Cannot redefine property: p
上面代碼中,使用Object.seal方法之后,屬性描述對(duì)象的configurable屬性就變成了false,然后改變enumerable屬性就會(huì)報(bào)錯(cuò)

8.2.2Object.seal只是禁止新增或刪除屬性,并不影響修改某個(gè)屬性的值。

var obj = { p: "a" };
Object.seal(obj);
obj.p = "b";
obj.p // "b"
上面代碼中,Object.seal方法對(duì)p屬性的value無效,是因?yàn)榇藭r(shí)p屬性的可寫性由writable決定。

Object.isSealed()
8.3Object.freeze()
使得這個(gè)對(duì)象實(shí)際上變成了常量
無法增刪改屬性
使用Object.freeze方法以后,Object.isSealed將會(huì)返回true,Object.isExtensible返回false

Object.isFrozen()
Object.isFrozen的一個(gè)用途是,確認(rèn)某個(gè)對(duì)象沒有被凍結(jié)后,再對(duì)它的屬性賦值。

var obj = {
p: "hello"
};

Object.freeze(obj);

if (!Object.isFrozen(obj)) {
obj.p = "world";
}

9.局限性
9.1可以通過改變原型對(duì)象,來為對(duì)象增加屬性

9.1.1一種解決方案是,把obj的原型也凍結(jié)住。

var obj = new Object();
Object.preventExtensions(obj);

var proto = Object.getPrototypeOf(obj);
Object.preventExtensions(proto);

proto.t = "hello";
obj.t // undefined

9.2如果屬性值是對(duì)象,上面這些方法只能凍結(jié)屬性指向的對(duì)象,而不能凍結(jié)對(duì)象本身的內(nèi)容
var obj = {
foo: 1,
bar: ["a", "b"]
};
Object.freeze(obj);

obj.bar.push("c");
obj.bar // ["a", "b", "c"]
上面代碼中,obj.bar屬性指向一個(gè)數(shù)組,obj對(duì)象被凍結(jié)以后,這個(gè)指向無法改變,即無法指向其他值,但是所指向的數(shù)組是可以改變的

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

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

相關(guān)文章

  • 標(biāo)準(zhǔn))屬性描述對(duì)象

    摘要:也就是說,屬性控制了屬性描述對(duì)象的可寫性??杀闅v性返回一個(gè)布爾值,表示目標(biāo)屬性是否可遍歷運(yùn)算符不管某個(gè)屬性是對(duì)象自身的還是繼承的,都會(huì)返回。上面的寫法與定義屬性描述對(duì)象是等價(jià)的,而且使用更廣泛。 屬性描述對(duì)象 概述Object.getOwnPropertyDescriptor()Object.getOwnPropertyNames()Object.defineProperty(),Ob...

    MartinDai 評(píng)論0 收藏0
  • JavaWEB開發(fā)11——JSP

    摘要:出現(xiàn)的目的同一樣也是要提到頁面中的腳本代碼。標(biāo)準(zhǔn)標(biāo)準(zhǔn)標(biāo)簽庫有個(gè)子庫,但隨著發(fā)展,目前常使用的是他的核心庫標(biāo)簽庫標(biāo)簽庫的前綴下載與導(dǎo)入下載從的網(wǎng)站下載的包。 一、JSP技術(shù)1.jsp腳本和注釋jsp腳本:1) ----- 內(nèi)部的java代碼翻譯到service方法的內(nèi)部2) ----- 會(huì)被翻譯成service方法內(nèi)部out.print()3) ---- 會(huì)被翻譯成servlet的成員的...

    beita 評(píng)論0 收藏0
  • Python標(biāo)準(zhǔn)---16、內(nèi)置類型:上下文管理器類型、其他、特殊屬性

    摘要:退出運(yùn)行時(shí)上下文并返回一個(gè)布爾值旗標(biāo)來表明所發(fā)生的任何異常是否應(yīng)當(dāng)被屏蔽。除了實(shí)現(xiàn)上下文管理協(xié)議以外,不同類型不會(huì)被特殊處理。其中一些并不會(huì)被內(nèi)置函數(shù)所列出。 上一篇文章:Python標(biāo)準(zhǔn)庫---15、內(nèi)置類型:集合類型、映射類型下一篇文章:Python標(biāo)準(zhǔn)庫---17、內(nèi)置異常 上下文管理器類型 Python 的 with 語句支持通過上下文管理器所定義的運(yùn)行時(shí)上下文這一概念。 此...

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

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

0條評(píng)論

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