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