摘要:對(duì)象直接量的默認(rèn)值表示能否通過(guò)循環(huán)返回屬性。同樣密封對(duì)象操作是不可逆的。代表未凍結(jié)已凍結(jié)屬性特性規(guī)則總結(jié)如果對(duì)象是不可拓展的,則可以編輯已有的自有屬性,但不能給它添加新屬性。
寫(xiě)在前面
注:這個(gè)系列是本人對(duì)js知識(shí)的一些梳理,其中不少內(nèi)容來(lái)自書(shū)籍:Javascript高級(jí)程序設(shè)計(jì)第三版和JavaScript權(quán)威指南第六版,感謝它們的作者和譯者。有發(fā)現(xiàn)什么問(wèn)題的,歡迎留言指出。
1.數(shù)據(jù)屬性數(shù)據(jù)屬性的4個(gè)特性:
Configurable:①表示能否通過(guò)delete刪除屬性從而重新定義,②能否修改屬性的特性,③能否把屬性修改為訪(fǎng)問(wèn)器屬性。對(duì)象直接量里默認(rèn)值true。
Enumerable:表示能否通過(guò)for-in循環(huán)返回屬性。對(duì)象直接量里默認(rèn)值true。
Writable:表示能否修改屬性的值。對(duì)象直接量里默認(rèn)值true。
Value:包含這個(gè)屬性的數(shù)據(jù)值。對(duì)象直接量里默認(rèn)值undefined。
//查看對(duì)象直接量的屬性的屬性特性默認(rèn)值 var people = { name:"jaychou", sayName:function () { console.log(this.name); } }; /**{value: "jaychou", writable: true, enumerable: true, configurable: true}*/ console.log(Object.getOwnPropertyDescriptor(people,"name")); /**{value: ?, writable: true, enumerable: true, configurable: true}*/ console.log(Object.getOwnPropertyDescriptor(people,"sayName")); //getOwnPropertyDescriptor對(duì)于繼承屬性和不存在的屬性,返回undefined
要修改屬性默認(rèn)的特性,使用Object.defineProperty()方法,接收3個(gè)參數(shù):對(duì)象,屬性名字和描述符對(duì)象。
//修改屬性默認(rèn)特性: Object.defineProperty(person,"job",{ emumerable:false,//不可枚舉 value:"singer", writable:false,//不可寫(xiě) configurable:true }); /**{name: "jaychou", sayName: ?, job: "singer"}*/ console.log(person); for(var prop in person){ //打印name,sayName console.log(prop); } //會(huì)報(bào)錯(cuò) try{ person.job = "director"; }catch (e) { //Cannot assign to read only property "job" of object console.log(e); }
可以多次調(diào)用Object.defineProperty()方法修改同一個(gè)屬性,但在把configurable特性設(shè)置為false之后就會(huì)有限制了:
Object.defineProperty(person,"height",{ configurable:false,//不可配置 writable:true, value:172 }); try{ Object.defineProperty(person,"height",{ configurable:true,//出錯(cuò) enumerable:true,//出錯(cuò) value:175,//正常 writable:false,//writable從true變false可以,false變true也會(huì)出錯(cuò) }); }catch (e) { //Cannot redefine property: height at Function.defineProperty console.log(e); } try{ delete person.height; }catch (e) { //設(shè)置成不可配置后也不可刪除:Cannot delete property "height" of #
另外,調(diào)用 Object.defineProperty()方法時(shí),如果不指定,configurable、enumerable 和 writable 特性的默認(rèn)值都是 false。如果是修改已有屬性,則無(wú)此限制。
2.存儲(chǔ)器屬性存儲(chǔ)器屬性不包含數(shù)據(jù)值,只包含包含 getter 和 setter 函數(shù)(非必需)。 在讀取存儲(chǔ)器屬性時(shí),會(huì)調(diào)用 getter 函數(shù),這個(gè)函數(shù)負(fù)責(zé)返回有效的值;在寫(xiě)入存儲(chǔ)器屬性時(shí),會(huì)調(diào)用 setter 函數(shù)并傳入新值,這個(gè)函數(shù)負(fù)責(zé)決定如何處理數(shù)據(jù)。4個(gè)屬性特性如下:
Configurable:①表示能否通過(guò)delete刪除屬性從而重新定義,②能否修改屬性的特性,③能否把屬性修改為數(shù)據(jù)屬性。對(duì)象直接量的默認(rèn)值true
Enumerable:表示能否通過(guò)for-in循環(huán)返回屬性。對(duì)象直接量的默認(rèn)值true
Get:在讀取屬性時(shí)調(diào)用的函數(shù)。對(duì)象直接量默認(rèn)值undefined
Set:在寫(xiě)入屬性時(shí)調(diào)用的函數(shù)。對(duì)象直接量的默認(rèn)值undefined
定義存儲(chǔ)器屬性最簡(jiǎn)單的方法是使用對(duì)象直接量語(yǔ)法的拓展寫(xiě)法:
var p = { x:3.0, y:4.0, //r是可讀寫(xiě)的存取器屬性 get r(){return Math.sqrt(this.x*this.x+this.y*this.y);}, set r(newValue){ var oldvalue = Math.sqrt(this.x*this.x+this.y*this.y); var ratio = newValue/oldvalue; this.x *= ratio; this.y *= ratio; }, //theta是只讀存取器屬性 get theta(){return Math.atan2(this.y,this.x);} } console.log(p.r); p.r = 25;
使用Object.defineProperty()方法定義存儲(chǔ)器屬性:
var book = { _year:2004, edition:1 }; Object.defineProperty(book,"year",{ get:function () { return this._year; }, set:function (newValue) { if(newValue>2004){ this._year = newValue; this.edition += newValue - 2004; } } }) /**{get: ?, set: ?, enumerable: false, configurable: false}*/ console.log(Object.getOwnPropertyDescriptor(book,"year"));
如例子所示,使用存儲(chǔ)器屬性的常見(jiàn)方式,即設(shè)置一個(gè)屬性的值會(huì)導(dǎo)致其他屬性發(fā)生變化。還有一種常見(jiàn)就是現(xiàn)在流行的類(lèi)似于Vue的響應(yīng)式原理,就是把data中的屬性都使用defineProperty修改為存儲(chǔ)器屬性,可以監(jiān)聽(tīng)到數(shù)據(jù)的變化。
3.定義多個(gè)屬性經(jīng)常要?jiǎng)?chuàng)建或修改多個(gè)屬性,這時(shí)候可以使用Object.defineProperties()方法,它接收2個(gè)參數(shù),要添加或修改屬性的對(duì)象和一個(gè)映射表,包含名稱(chēng)和屬性描述符。
var book1 = {}; Object.defineProperties(book1,{ _year:{ value:"2008" }, editor:{ enumerable:true, value:"2" }, year:{ get:function () { return this._year; }, set:function (newValue) { this._year = newValue; this.edition += newValue - 2004; } } });4.對(duì)象的可擴(kuò)展性
對(duì)象的可拓展性表示是否可以給對(duì)象添加新屬性。所有內(nèi)置對(duì)象和自定義對(duì)象都是顯式可擴(kuò)展的,宿主對(duì)象的可擴(kuò)展性是由Javascript引擎定義的。
var teacher = {age:25}; //true:代表可拓展 console.log(Object.isExtensible(teacher));
Object.preventExtensions(teacher); //false console.log(Object.isExtensible(teacher)); try{ teacher.subject = "math"; }catch (e) { //TypeError: Cannot add property subject, object is not extensible console.log(e); }
轉(zhuǎn)換成不可拓展的操作是不可逆的,而且只能影響到對(duì)象本身的可拓展性,如果給一個(gè)不可拓展對(duì)象的原型添加屬性,這個(gè)不可拓展對(duì)象同樣會(huì)繼承這些新屬性。
5.密封對(duì)象密封對(duì)象比鎖定對(duì)象更高一層,除了不可拓展以外,對(duì)象的所有自身屬性都設(shè)置成了不可配置的。同樣密封對(duì)象操作是不可逆的。
var tea1 = {subject:"math"}; //false:代表未密封 console.log(Object.isSealed(tea1)); Object.seal(tea1); try{ Object.defineProperty(tea1,"subject",{ //enumerable:false,//出錯(cuò) //configurable:true,//出錯(cuò) writable:false//和上面說(shuō)的一樣,writable從true變成false可以,false變成true則出錯(cuò) }); }catch (e) { console.log("出錯(cuò).."); console.log(e); } //true:已密封 console.log(Object.isSealed(tea1));6.凍結(jié)對(duì)象
凍結(jié)比密封對(duì)象多的效果是:可以將它自有的所有數(shù)據(jù)屬性設(shè)置為只讀(如果對(duì)象的存取器屬性具有setter方法,存取器屬性將不受影響,仍可以通過(guò)給屬性賦值調(diào)用它們)。
var tea2 = {subject:"Chinese"}; //false:代表未凍結(jié) console.log(Object.isFrozen(tea2)); Object.freeze(tea2); try{ tea2.subject = "math"; }catch (e) { //TypeError: Cannot assign to read only property "subject" of object console.log(e); } //true:已凍結(jié) console.log(Object.isFrozen(tea2));7.屬性特性規(guī)則總結(jié)
如果對(duì)象是不可拓展的,則可以編輯已有的自有屬性,但不能給它添加新屬性。
如果屬性是不可配置的,則不能修改它的可配置性和可枚舉性。
如果存取器屬性是不可配置的,則不能修改其getter和setter方法,也不能將它轉(zhuǎn)換為數(shù)據(jù)屬性。
如果數(shù)據(jù)屬性是不可配置的,則不能將它轉(zhuǎn)換為存取器屬性。
如果數(shù)據(jù)屬性是不可配置的,則不能將它的可寫(xiě)性從false修改為true,但可以從true修改為false。
如果數(shù)據(jù)屬性是不可配置且不可寫(xiě)的,則不能修改它的值。然而可配置但不可寫(xiě)屬性的值是可以修改的(做法:先將它標(biāo)記為可寫(xiě)的,然后修改它的值,最后轉(zhuǎn)換為不可寫(xiě)的)。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/108374.html
摘要:構(gòu)造函數(shù)調(diào)用會(huì)使用新創(chuàng)建的對(duì)象作為調(diào)用上下文。函數(shù)的參數(shù)相關(guān)可選形參當(dāng)傳入的實(shí)參比函數(shù)聲明時(shí)指定的形參數(shù)量要少,剩下的形參都將設(shè)置為值實(shí)參多則會(huì)自動(dòng)省略。它們的第一個(gè)實(shí)參是要調(diào)用函數(shù)的母對(duì)象,它是調(diào)用上下文,函數(shù)體內(nèi)通過(guò)引用它。 寫(xiě)在前面 注:這個(gè)系列是本人對(duì)js知識(shí)的一些梳理,其中不少內(nèi)容來(lái)自書(shū)籍:Javascript高級(jí)程序設(shè)計(jì)第三版和JavaScript權(quán)威指南第六版,感謝它們的...
摘要:插件開(kāi)發(fā)前端掘金作者原文地址譯者插件是為應(yīng)用添加全局功能的一種強(qiáng)大而且簡(jiǎn)單的方式。提供了與使用掌控異步前端掘金教你使用在行代碼內(nèi)優(yōu)雅的實(shí)現(xiàn)文件分片斷點(diǎn)續(xù)傳。 Vue.js 插件開(kāi)發(fā) - 前端 - 掘金作者:Joshua Bemenderfer原文地址: creating-custom-plugins譯者:jeneser Vue.js插件是為應(yīng)用添加全局功能的一種強(qiáng)大而且簡(jiǎn)單的方式。插....
摘要:關(guān)鍵字計(jì)算為當(dāng)前執(zhí)行上下文的屬性的值。毫無(wú)疑問(wèn)它將指向了這個(gè)前置的對(duì)象。構(gòu)造函數(shù)也是同理。嚴(yán)格模式無(wú)論調(diào)用位置,只取顯式給定的上下文綁定的,通過(guò)方法傳入的第一參數(shù),否則是。其實(shí)并不屬于特殊規(guī)則,是由于各種事件監(jiān)聽(tīng)定義方式本身造成的。 this 是 JavaScript 中非常重要且使用最廣的一個(gè)關(guān)鍵字,它的值指向了一個(gè)對(duì)象的引用。這個(gè)引用的結(jié)果非常容易引起開(kāi)發(fā)者的誤判,所以必須對(duì)這個(gè)關(guān)...
摘要:如果看完本文后,還對(duì)進(jìn)程線(xiàn)程傻傻分不清,不清楚瀏覽器多進(jìn)程瀏覽器內(nèi)核多線(xiàn)程單線(xiàn)程運(yùn)行機(jī)制的區(qū)別。因此準(zhǔn)備梳理這塊知識(shí)點(diǎn),結(jié)合已有的認(rèn)知,基于網(wǎng)上的大量參考資料,從瀏覽器多進(jìn)程到單線(xiàn)程,將引擎的運(yùn)行機(jī)制系統(tǒng)的梳理一遍。 前言 見(jiàn)解有限,如有描述不當(dāng)之處,請(qǐng)幫忙及時(shí)指出,如有錯(cuò)誤,會(huì)及時(shí)修正。 ----------超長(zhǎng)文+多圖預(yù)警,需要花費(fèi)不少時(shí)間。---------- 如果看完本文后,還...
摘要:前言見(jiàn)解有限,如有描述不當(dāng)之處,請(qǐng)幫忙指出,如有錯(cuò)誤,會(huì)及時(shí)修正。為什么要梳理這篇文章最近恰好被問(wèn)到這方面的問(wèn)題,嘗試整理后發(fā)現(xiàn),這道題的覆蓋面可以非常廣,很適合作為一道承載知識(shí)體系的題目。 前言 見(jiàn)解有限,如有描述不當(dāng)之處,請(qǐng)幫忙指出,如有錯(cuò)誤,會(huì)及時(shí)修正。 為什么要梳理這篇文章? 最近恰好被問(wèn)到這方面的問(wèn)題,嘗試整理后發(fā)現(xiàn),這道題的覆蓋面可以非常廣,很適合作為一道承載知識(shí)體系的題目...
閱讀 3404·2022-01-04 14:20
閱讀 3118·2021-09-22 15:08
閱讀 2209·2021-09-03 10:44
閱讀 2324·2019-08-30 15:44
閱讀 1501·2019-08-29 18:40
閱讀 2669·2019-08-29 17:09
閱讀 2996·2019-08-26 13:53
閱讀 3227·2019-08-26 13:37