摘要:上一篇面向?qū)ο蟀鎵K之理解對象下一篇面向?qū)ο蟀鎵K之定義多個對象屬性以及讀取屬性特性
這是 javascript 面向?qū)ο蟀鎵K的第二篇文章,主要講解的是對象的屬性,首先創(chuàng)建一個對象:
var person = { name: "Nicholas", age: 29, job: "Software Engineer", sayName: function () { console.log(this.name); } };
上面的例子創(chuàng)建了一個名為 person 的對象,并為它添加了三個屬性( name 、 age 和 job )和一個方法( sayName() )。其中, sayName() 方法用于顯示 this.name (將被解析為 person.name )的值。
ECMAScript 中有兩種屬性:數(shù)據(jù)屬性和訪問器屬性。
數(shù)據(jù)屬性是可獲取和設置值得屬性,數(shù)據(jù)屬性將 value 和 writable 屬性包含在其描述符中。數(shù)據(jù)屬性有4個描述其行為的特性:
[[Configurable]]:表示能否通過 delete 刪除屬性從而重新定義屬性,能否修改屬性的特性,或者能否把屬性修改為訪問器屬性。像前面例子中那樣直接在對象上定義的屬性,它們的這個特性默認值為 true 。
[[Enumerable]]:表示能否通過 for-in 循環(huán)返回屬性。像前面例子中那樣直接在對象上定義的屬性,它們的這個特性默認值為 true 。
[[Writable]]: 表示能否修改屬性的值。像前面例子中那樣直接在對象上定義的屬性,它們的這個特性默認值為 true 。
[[Value]]: 包含這個屬性的數(shù)據(jù)值。讀取屬性值的時候,從這個位置讀;寫入屬性值的時候,把新值保存在這個位置。這個特性的默認值為 undefined 。
對于像前面例子中那樣直接在對象上定義的屬性,它們的 [[Configurable]] 、 [[Enumerable]]和 [[Writable]] 特性都被設置為 true ,而 [[Value]] 特性被設置為指定的值。例如:
var person = { name: "Nicholas", };
這里創(chuàng)建了一個名為 name 的屬性,為它指定的值是 "Nicholas" 。也就是說, [[Value]] 特性將被設置為 "Nicholas" ,而對這個值的任何修改都將反映在這個位置。
此時有這樣一個想法,如果我不允許修改 name 屬性的值,怎么辦?或者說我要修改屬性的默認特性,怎樣才可以實現(xiàn)呢?要實現(xiàn)這些功能就要用到 Object.defineProperty()方法,這個方法接收三個參數(shù):屬性所在的對象、屬性的名字和一個描述符對象。其中,描述符(descriptor)對象的屬性必須是: configurable 、 enumerable 、 writable 和 value 。設置其中的一或多個值,可以修改對應的特性值。例如:
var person = {}; Object.defineProperty(person, "name", { writable: false, value: "Nicholas" }) console.log(person.name); // Nicholas person.name = "Greg"; console.log(person.name); // Nicholas
這個例子創(chuàng)建了一個 name 屬性,它的值 "Nicholas" 是只讀的。這個屬性不可修改,如果嘗試修改這個值的話在非嚴格模式下會被忽略,但是如果在嚴格模式下,會拋出錯誤:
Uncaught TypeError: Cannot assign to read only property "name" of object "#
var person = {}; Object.defineProperty(person, "name", { configurable: false, value: "Nicholas" }) console.log(person.name); // Nicholas delete person.name; console.log(person.name); // Nicholas
把 configurable 設置為 false ,表示不能從對象中刪除屬性。如果對這個屬性調(diào)用 delete ,則在非嚴格模式下什么也不會發(fā)生,而在嚴格模式下會導致錯誤。而且一旦把屬性定義為不可配置,就不能再把它變回可配置了。此時,再調(diào)用 Object.defineProperty() 方法修改特性,都會導致錯誤:
var person = {}; Object.defineProperty(person, "name", { configurable: false, value: "Nicholas" }) console.log(person.name); // Nicholas /* delete person.name; console.log(person.name); // Nicholas */ Object.defineProperty(person, "name", { writable: true })
也就是說 可以多次調(diào)用 Object.defineProperty() 方法修改同一屬性,但是當 configurable 設置為 false 后就不可以了。
在《JavaScript 高級程序設計(第三版)》中寫到:
“一旦把屬性定義為不可配置的,就不能再把它變回可配置了。此時,再調(diào)用 Object.defineProperty() 方法修改除 writable 之外的特性,都會導致錯誤。”
但是我試了一些,即使修改的是 writable 屬性,還是會報錯。如果我描述的有錯,還望各位大佬指出,以便交流。
在調(diào)用 Object.defineProperty() 來定義屬性時。如果不指定, configurable 、 enumerable 和writable 特性的默認值都是 false。其實在日常的開發(fā)中用到這種高級方法來定義屬性的機會還是比較少,不過理解這部分對理解對象還是有很大的好處。
訪問器屬性訪問器屬性不包含數(shù)據(jù)值,但包含一對兒 getter 和 setter 函數(shù)(不過,這兩個函數(shù)都不是必需的)。在讀取訪問器屬性的時候,會調(diào)用 getter 方法,這個函數(shù)復制返回有效的值;在寫入訪問器屬性的時候,會調(diào)用 setter 函數(shù),這個函數(shù)復制如果修改數(shù)據(jù)。訪問器屬性有如下 4 個特性:
[[Configurable]] :表示能否通過 delete 刪除屬性從而重新定義屬性,能否修改屬性的特性,或者能否把屬性修改為數(shù)據(jù)屬性。對于直接在對象上定義的屬性,這個特性的默認值為true 。
[[Enumerable]] :表示能否通過 for-in 循環(huán)返回屬性。對于直接在對象上定義的屬性,這個特性的默認值為 true 。
[[Get]] :在讀取屬性時調(diào)用的函數(shù)。默認值為 undefined 。
[[Set]] :在寫入屬性時調(diào)用的函數(shù)。默認值為 undefined 。訪問器屬性不能直接定義,必須使用 Object.defineProperty() 來定義。請看下面的例子。
var book = { _year: 2004, edition: 1 } Object.defineProperty(book, "year", { get: function () { return this._year; }, set: function (newVal) { if (newVal > this._year) { this._year = newVal; return this.edition += newVal - 2004; } } }) book.year = 2005; console.log(book.edition); // 2
以上代碼代碼創(chuàng)建了一個 book 對象,定義了兩個屬性,_year 和 edition。而訪問器屬性 year 包含了一個 geter 函數(shù)和 setter 函數(shù)。getter 函數(shù)返回 _year 的值,而 setter 函數(shù)返正確的版本。當把 year 屬性修改成 2005 時,而 edition 變?yōu)?2,這是使用訪問器屬性的常見方式,即設置一個屬性的值會導致其他屬性發(fā)生變化。
不一定非要同時指定 getter 和 setter,如果只指定 getter ,表明該屬性不能寫,只能讀取,嘗試寫入屬性會被忽略,但在嚴格模式下會報錯。如果只指定 setter ,表明該屬性不能讀取,如果嘗試讀取,在嚴格模式和非嚴格模式下都會返回 undefined。
在《JavaScript 高級程序設計(第三版)》中寫到:小結(jié)
“只指定 setter 函數(shù)的屬性也不能讀,否則在非嚴格模式下會返回 undefined ,而在嚴格模式下會拋出錯誤。”
但在 chrome 中測試了一下,在嚴格模式下不會拋出錯誤,返回的也是 undefined 。如果我描述的有錯,還望各位大佬指出,以便交流。
本片博客主要介紹了兩種屬性:數(shù)據(jù)屬性和訪問器屬性,介紹了這兩種屬性的定義以及這兩種屬性的特性,主要使用方法 Object.defineProperty()。其實這篇文章主要是加強對對象的理解。
上一篇:javascript 面向?qū)ο蟀鎵K之理解對象
下一篇:javascript 面向?qū)ο蟀鎵K之定義多個對象屬性以及讀取屬性特性
文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/93176.html
摘要:用代碼可以這樣描述安全到達國外面向過程既然說了面向?qū)ο?,那么與之對應的就是面向過程。小結(jié)在這篇文章中,介紹了什么是面向?qū)ο蠛兔嫦蜻^程,以及中對象的含義。 這是 javascript 面向?qū)ο蟀鎵K的第一篇文章,主要講解對面向?qū)ο笏枷氲囊粋€理解。先說說什么是對象,其實這個還真的不好說。我們可以把自己當成一個對象,或者過年的時候相親,找對象,那么你未來的老婆也是一個對象。我們就要一些屬性,比...
摘要:返回值是一個對象,如果是訪問器屬性,這個對象的屬性有和如果是數(shù)據(jù)屬性,這個對象的屬性有和。上一篇面向?qū)ο蟀鎵K之對象屬性下一篇面向?qū)ο蟀鎵K之創(chuàng)建對象 這是 javascript 面向?qū)ο蟀鎵K的第三篇文章,主要講解的是多個屬性的定義以及讀取屬性的特性。前面這幾章內(nèi)容目的在于加深對對象的理解,這樣可以利于理解后面的原型鏈以及繼承方面的知識,或者你也可以了解一下不一樣的 javascript ...
摘要:一個不相關的總結(jié)鄙人現(xiàn)在寫代碼容易用一句話總結(jié)根本停不下來。這種狀況讓人生活狀態(tài)極差,黑夜白天顛倒,飽一頓餓一頓,體質(zhì)下降,妹紙盡失我要遠離這種狀態(tài)。所以決定以后寫代碼盡可能只寫到點,要緊的話再趕趕,一般就停下來寫寫總結(jié)泡泡腳藍后碎覺。 1、OOP在粗粒度上面向?qū)ο?,在細粒度上面向過程:即總體上看起來是一個模塊一個模塊的,細分起來還是需要一步一步執(zhí)行的; 2、OOP提高了代碼重用效率,...
摘要:又將整個文藝類閱讀系統(tǒng)的業(yè)務劃分為兩大部分,分別是面向管理員和合作作者的后臺管理系統(tǒng)和面向用戶的移動端,系統(tǒng)的需求分析將圍繞這兩部分進行展開。 效果展示 showImg(https://user-gold-cdn.xitu.io/2018/8/26/16576a709bd02f5f?w=1409&h=521&f=gif&s=30128195); showImg(https://user...
摘要:又將整個文藝類閱讀系統(tǒng)的業(yè)務劃分為兩大部分,分別是面向管理員和合作作者的后臺管理系統(tǒng)和面向用戶的移動端,系統(tǒng)的需求分析將圍繞這兩部分進行展開。 效果展示 showImg(https://user-gold-cdn.xitu.io/2018/8/26/16576a709bd02f5f?w=1409&h=521&f=gif&s=30128195); showImg(https://user...
閱讀 1424·2021-11-11 16:54
閱讀 2448·2021-09-22 10:51
閱讀 2707·2019-08-30 15:44
閱讀 3261·2019-08-29 17:05
閱讀 1509·2019-08-29 17:01
閱讀 2981·2019-08-29 12:28
閱讀 2539·2019-08-26 13:50
閱讀 1798·2019-08-23 16:47