摘要:枚舉對象的屬性第二種情況設置為,可以被枚舉。內置對象訪問器屬性方法介紹摘自方法返回指定對象上一個自有屬性對應的屬性描述符。對象中存在的屬性描述符主要有數據描述符和訪問器描述符兩種返回傳遞給函數的對象參考中的
1. 什么是對象
對象是無序屬性的集合
創建自定義對象最簡單的方式就是以字面量的形式創建對象(或創建一個Object實例),然后再為它添加屬性和方法,如下所示:
var person = { name: "Nicholas", age: 29, sayHi: function() { console.log(this.name); } }
但是我們需要定義對象中的某個屬性能否修改,能夠重寫等屬性,那我們應該如何定義
2. 內置屬性—數據屬性Object.defineProperty()方法介紹(摘自MDN)
Object.defineProperty() 方法會直接在一個對象上定義一個新屬性,或者修改一個對象的現有屬性,并返回這個對象
語法:Object.defineProperty(obj, prop, descriptor)
參數:
(1)obj:需要被操作的目標對象
(2)prop:目標對象需要定義或修改的屬性的名稱
(3)descriptor:將被定義或修改的屬性的描述符
返回:被傳遞給函數的對象
是否可以刪除目標屬性或是否可以再次修改屬性的特性(writable, configurable, enumerable)。默認為false
設置為true可以被刪除或可以重新設置特性;
設置為false,不能被可以被刪除或不可以重新設置特性,只能將writable從true置為false
一旦把屬性定義為不可配置的,就不能再把它便會可配置的,這一點很重要
主要起到數據的保護作用,決定了目標屬性是否可以使用delete刪除,是否可以再次設置特性
//-----------------測試目標屬性是否能被刪除------------------------ var obj = {} // 第一種情況:configurable設置為true,可以被刪除。 Object.defineProperty(obj, "newKey", { value: "hello", configurable: true }); // 刪除屬性 delete obj.newKey; console.log( obj.newKey ); //undefined // 第二種情況:configurable設置為false,不能被刪除。 Object.defineProperty(obj, "newKey", { value: "hello", configurable: false }); // 刪除屬性 delete obj.newKey; console.log( obj.newKey ); //hello //-----------------測試是否可以再次修改特性------------------------ var obj = {} //第一種情況:configurable設置為false,不能再次修改特性。 Object.defineProperty(obj, "newKey", { value: "hello", writable: false, enumerable: false, configurable: false }); //重新修改特性 Object.defineProperty(obj, "newKey", { value: "hello", writable: true, enumerable: true, configurable: true }); console.log( obj.newKey ); //報錯:Uncaught TypeError: Cannot redefine property: newKey //第二種情況:configurable設置為true,可以再次修改特性。 Object.defineProperty(obj, "newKey", { value: "hello", writable: false, enumerable: false, configurable: true }); //重新修改特性 Object.defineProperty(obj, "newKey", { value: "hello", writable: true, enumerable: true, configurable: true }); console.log( obj.newKey ); //hello2.2 enumerable 屬性
此屬性是否可以被枚舉(使用for...in或Object.keys())默認為false
設置為true可以被枚舉;設置為false,不能被枚舉
var obj = {} // 第一種情況:enumerable設置為false,不能被枚舉。 Object.defineProperty(obj, "newKey", { value: "hello", writable: false, enumerable: false }); // 枚舉對象的屬性 for( var attr in obj ){ console.log( attr ); // undefined } // 第二種情況:enumerable設置為true,可以被枚舉。 Object.defineProperty(obj, "newKey", { value: "hello", writable: false, enumerable: true }); // 枚舉對象的屬性 for( var attr in obj ){ console.log( attr ); //newKey }2.3 value 屬性
屬性對應的值,可以是任意類型的值,默認為undefined;
var obj = {} // 第一種情況:不設置value屬性 Object.defineProperty(obj, "key", {}); console.log( obj.key ); //undefined // 第二種情況:設置value屬性 Object.defineProperty(obj, "key", { value: "hello" }); console.log( obj.key ); //hello // 同字面定義的數據值對應2.4 writable 屬性
屬性的值是否可以被重寫。默認為false
設置為true可以被重寫;設置為false,不能被重寫
var obj = {} // 第一種情況:writable設置為false,不能重寫。 Object.defineProperty(obj, "newKey", { value: "hello", writable: false }); // 更改newKey的值 obj.newKey = "change value"; console.log( obj.newKey ); //hello // 第二種情況:writable設置為true,可以重寫 Object.defineProperty(obj, "newKey", { value: "hello", writable: true }); // 更改newKey的值 obj.newKey = "change value"; console.log( obj.newKey ); //change value2.5 默認值理解(重點)
在調用 Object.defineProperty 方法給對象添加屬性時,如果不指定,configurable、enumerable、writable這些值都為默認的false
==> 使用 Object.getOwnPropertyDescriptor() 方法來查看對象的內置屬性
var obj = {}; // 第一種情況:使用 Object.defineProperty() 定義屬性 Object.defineProperty(obj, "key", { value: "hello" }); Object.getOwnPropertyDescriptor(obj, "key"); // {value: "hello", writable: false, enumerable: false, configurable: false} // 第二種情況:字面量方式 obj.key = "hello"; Object.getOwnPropertyDescriptor(obj, "key"); // {value: "hello", writable: true, enumerable: true, configurable: true}2.6 數據屬性總結
configurable: 目標屬性是否可以被刪除或是否可以再次修改特性 true | false
enumerable: 目標屬性是否可以被枚舉。true | false
value: 設置屬性的值 undefined
writable: 值是否可以重寫。true | false
3. 內置對象—訪問器屬性Object.getOwnPropertyDescriptor()方法介紹(摘自MDN)
Object.getOwnPropertyDescriptor() 方法返回指定對象上一個自有屬性對應的屬性描述符。(自有屬性指的是直接賦予該對象的屬性,不需要從原型鏈上進行查找的屬性)
語法:Object.getOwnPropertyDescriptor(obj, prop)
參數:
(1)obj:需要被操作的目標對象
(2)prop:目標對象內屬性名稱(String類型)
返回:如果指定的屬性存在于對象上,則返回其屬性描述符對象(property descriptor),否則返回 undefined
參照數據屬性中的configurable屬性
3.2 enumerable 屬性參照數據屬性中的enumerable屬性
3.3 get 方法在讀取屬性是調用的函數,默認值為undefined
var obj = {}, value = "hello"; Object.defineProperty(obj, "key", { get: function() { console.log("獲取obj.key的值上下文"); return value; } }); console.log(obj.key); // "獲取obj.key的值上下文" hello obj.key = "new value"; console.log(obj.key); // "獲取obj.key的值上下文" hello3.4 set 方法
在寫入屬性時調用的函數,默認值為undefined
// 一般不會多帶帶為屬性設置set而不設置get var obj = {}, value = "hello"; Object.defineProperty(obj, "key", { set: function(val) { console.log("設置obj.key的值上下文"); } }); obj.key = "new value"; // "獲取obj.key的值上下文" console.log(obj.key); // undefined
不一定非要同時指定getter和setter。只指定getter意味著屬性是不能寫,嘗試寫入屬性會被忽略。在嚴格模式下,嘗試寫入只指定getter函數的屬性會拋出錯誤。類似的,只指定setter函數的屬性也不能讀,否則在非嚴格模式下會返回undefined,而在嚴格模式下會拋出錯誤。
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; } } }); book.year = 2005; alert(book.edition); //2
使用訪問器屬性的常見方式,即設置一個屬性的值會導致其他屬性發生變化
3.5 數據和視圖聯動(重點)給對象o定義新的屬性b,并且定義屬性b的get和set方法,當o.b的時候會調用b屬性的get方法,給b屬性賦值的時候,會調用set方法,這就是修改數據的時候,視圖會自動更新的關鍵前端獲取數據后,需要根據數據操作dom,視圖變化后,需要修改不少代碼,有沒有方法將數據和dom操作隔離,看一個例子
你好,
// 視圖控制器 var userInfo = {}; Object.defineProperty(userInfo, "nickName", { get: function(){ return document.getElementById("nickName").innerHTML; }, set: function(nick){ document.getElementById("nickName").innerHTML = nick; } }); Object.defineProperty(userInfo, "introduce", { get: function(){ return document.getElementById("introduce").innerHTML; }, set: function(introduce){ document.getElementById("introduce").innerHTML = introduce; } }); // 數據 // todo 獲取用戶信息的代碼 // .... userInfo.nickName = "xxx"; userInfo.introduce = "我是xxx,我來自云南,..."
訪問器屬性是實現MVVM框架的核心原理哦~
4. 定義多個屬性Object.defineProperties() 方法直接在一個對象上定義新的屬性或修改現有屬性,并返回該對象
語法:Object.defineProperties(obj, props)
參數:
(1)obj:在其上定義或修改屬性的對象
(2)props:要定義其可枚舉屬性或修改的屬性描述符的對象。對象中存在的屬性描述符主要有數據描述符和訪問器描述符兩種
返回:傳遞給函數的對象
var obj = {}; Object.defineProperties(obj, { "property1": { value: true, writable: true }, "property2": { value: "Hello", writable: false } // etc. etc. });
參考:
Javascript中的Object.defineProperty
MDN Object.defineProperty
MDN Object.getOwnPropertyDescriptor
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/89413.html
摘要:說明此摘要筆記系列是我最近看高級程序設計第版隨手所記。其中,描述符對象的屬性必須是設置其中一個或多個值,可以修改對應的特性值。如支持的瀏覽器,可以取得指定屬性的描述符。 說明: 此摘要筆記系列是我最近看《JavaScript高級程序設計(第3版)》隨手所記。里面分條列舉了一些我認為重要的、需要記下的、對我有幫助的點,是按照我看的順序來的。摘要筆記本身沒有系統性,沒有全面性可言,寫在這里...
摘要:上一篇你不知道的筆記寫在前面這是年第一篇博客,回顧去年年初列的學習清單,發現僅有部分完成了。當然,這并不影響年是向上的一年在新的城市穩定連續堅持健身三個月早睡早起游戲時間大大縮減,學會生活。 上一篇:《你不知道的javascript》筆記_this 寫在前面 這是2019年第一篇博客,回顧去年年初列的學習清單,發現僅有部分完成了。當然,這并不影響2018年是向上的一年:在新的城市穩定、...
摘要:創建對象中,創建對象的基本模式有三種。因此,在設計構造函數時,需要進行慎重考慮。因此在中,這種問題被稱作繼承破壞封裝。靜態成員每個只有一份,直接通過類對象進行訪問。 什么是封裝 找工作時一些公司給了offer后我就想知道真正拿到手的是多少,畢竟賦稅繁重。但各種稅也好,五險一金也好我實在是弄不清楚,于是我就會在網上的一些稅后收入計算器上進行計算,只需要填寫一些基本信息,比如稅前收入,所...
摘要:把對象定義為無序屬性的集合,其屬性可以包含基本值對象或函數。接受兩個參數屬性所在的對象和要讀取其特性的屬性名返回的時其特性的對象例如讀高級程序設計這本書的第章面向對象的程序設計,我做了篇筆記。這是第一篇,后面還有兩篇,分別是封裝類和繼承。 ECMA-262把對象定義為:無序屬性的集合,其屬性可以包含基本值、對象或函數。所以,我們可以理解對象就是名值對的集合,名就是對象的每個屬性的名字,...
摘要:在創建子類型的實例時,不能向超類型的構造函數中傳遞參數。實際上,應該說是沒有辦法在不影響所有對象實例的情況下,給超類型的構造函數傳遞參數。 面向對象的語言有一個標志,那就是它們都有類的概念,而通過類可以創建任意多個具有相同屬性和方法的對象。 理解對象 創建自定義對象的最簡單的方法就是創建一個Object的實例,然后再為它添加屬性和方法。例如: var person = new Obje...
閱讀 695·2021-11-15 11:37
閱讀 3316·2021-10-27 14:14
閱讀 6038·2021-09-13 10:30
閱讀 2961·2021-09-04 16:48
閱讀 1926·2021-08-18 10:22
閱讀 2125·2019-08-30 14:19
閱讀 729·2019-08-30 10:54
閱讀 1745·2019-08-29 18:40