JS基礎(chǔ)之面向?qū)ο?基礎(chǔ)

屬性類型

說(shuō)到屬性類型拆挥,指的是一個(gè)對(duì)象所擁有的所有屬性的特征薄霜。包括兩類:數(shù)據(jù)屬性訪問(wèn)器屬性
屬性類型的存在就是為了描述對(duì)象屬性的各種特性纸兔,當(dāng)初是為了實(shí)現(xiàn)js引擎用的惰瓜,因此在js中不能直接訪問(wèn),也可以理解為它是一個(gè)隱式的食拜,例如:[[prototype]]

數(shù)據(jù)屬性

數(shù)據(jù)屬性包含有一個(gè)數(shù)據(jù)值的位置鸵熟。在這個(gè)位置可以進(jìn)行數(shù)據(jù)的讀寫副编。數(shù)據(jù)屬性有4個(gè)描述其行為的特性负甸。
[[Configurable]]:表示能否通過(guò)delete刪除屬性從而重新定義屬性,也包括能否修改屬性的特性痹届,或者能否把屬性修改為訪問(wèn)器屬性呻待。默認(rèn)值為true
[[Enurmerable]]:表示能否通過(guò)for-in循環(huán)返回屬性,說(shuō)白了是否能遍歷队腐,或者可枚舉蚕捉。默認(rèn)值為true
[[Writable]]:表示能否修改屬性的值,例如通過(guò)Object.defineProperty()方法修改屬性的值柴淘。默認(rèn)值為true
[[Value]]:包含這個(gè)屬性的數(shù)據(jù)值迫淹。讀取屬性值的時(shí)候,從這個(gè)位置讀为严。寫入屬性值的時(shí)候敛熬,把新的值保存在這個(gè)位置。默認(rèn)為undefined
例如:

let person = {
  name: 'zhd',
  age: 18,
  sex: 'boy'
}

上面我定義了一個(gè)名為person的變量第股,并且添加了三個(gè)對(duì)應(yīng)的屬性应民,并指定對(duì)應(yīng)的值。也就是說(shuō)三個(gè)屬性對(duì)應(yīng)的個(gè)子的[[Value]]這個(gè)特性就被賦予zhd,18,boy這三個(gè)值夕吻,以后對(duì)每個(gè)值得修改都會(huì)體現(xiàn)在這個(gè)位置上诲锹。
但是,如果要修改屬性默認(rèn)的特性涉馅,必須使用Object.defineProperty()方法归园。
Object.defineProperty():此方法接受三個(gè)參數(shù),第一個(gè)就是要修改的屬性所在的對(duì)象稚矿,第二個(gè)是要修改屬性名庸诱,第三個(gè)是描述符對(duì)象悬钳。這里需要注意一點(diǎn):描述符對(duì)象的屬性必須是configurable,enumerable,writable,value這四個(gè)。設(shè)置其中一個(gè)或多個(gè)值偶翅,可以修改對(duì)應(yīng)的特性值默勾。
例如:

var person = {}
Object.defineProperty(person, 'name', {
  writable: false,
  value: 'zhd'
})
console.log(person.name) // zhd
person.name = 'zy'
console.log(person.name) // zhd

如上面例子所示,修改了writable特性值為false,也就是不可寫或者說(shuō)不可更改聚谁,意思是一旦我設(shè)定了value特性母剥,并且將其writable設(shè)置為false,后續(xù)的所有更改name屬性值得行為都將不起作用形导。
這個(gè)規(guī)則同樣適用configurable环疼,例如:

var person = {}
Object.defineProperty(person, 'name', {
  configurable: false,
  value: 'zhd'
})
console.log(person.name) // zhd
person.name = 'zy'
console.log(person.name) // zhd

configurable設(shè)置為false,說(shuō)明不能用delete刪除屬性朵耕。一旦把屬性定義為不可配置的炫隶,就不能把它變回可配置的。此時(shí)阎曹,如果再次調(diào)用Object.defineProperty()方法修改除writable外的所有屬性伪阶,都會(huì)導(dǎo)致錯(cuò)誤。
如下圖所示:

WechatIMG18.png

而對(duì)于enumerable处嫌,和writable這兩個(gè)特性來(lái)說(shuō)栅贴,就好理解了,直接看定義就好了熏迹。

訪問(wèn)器屬性

訪問(wèn)器屬性不包含數(shù)據(jù)值檐薯;它們包含一對(duì)gettersetter函數(shù)。在讀取訪問(wèn)器屬性是注暗,會(huì)直接調(diào)用getter函數(shù)坛缕,也就是說(shuō)getter函數(shù)就相當(dāng)于訪問(wèn)的屬性值,這個(gè)函數(shù)負(fù)責(zé)返回有效的值捆昏。在寫入訪問(wèn)器屬性時(shí)赚楚,會(huì)調(diào)用setter函數(shù)并傳入新值,這個(gè)函數(shù)負(fù)責(zé)決定如何處理數(shù)據(jù)屡立。同樣的直晨,訪問(wèn)器屬性除了同數(shù)據(jù)屬性一樣,有[[Configurable]][[Enumerable]]這兩個(gè)特性外膨俐,還有兩個(gè)特性:
[[Get]]:在讀取屬性時(shí)調(diào)用的函數(shù)勇皇。默認(rèn)值為undefined
[[Set]]:在寫入屬性時(shí)調(diào)用的函數(shù)。默認(rèn)值為undefined
不過(guò)焚刺,訪問(wèn)器屬性不能直接定義敛摘,必須使用Object.defineProperty()方法來(lái)定義。

var person = {
  year: 4,
  edition: 1
}
Object.defineProperty(person, 'year', {
  get: function() {
    return this.year
  },
  set: function(newValue) {
    if (newValue > 4) {
      this.year = newValue
      this.edition += newValue - 4
    }
  }
})
person.year = 5
alert(person.edition) // 2

如上例子所示:每次訪問(wèn)year屬性值乳愉,都會(huì)調(diào)用year屬性本身的一個(gè)get函數(shù)兄淫,這個(gè)函數(shù)負(fù)責(zé)把year屬性值返回出去屯远。而如果要修改year屬性值,則會(huì)調(diào)用year屬性本身的一個(gè)set函數(shù)捕虽,而修改的值則會(huì)當(dāng)做參數(shù)傳入這個(gè)set函數(shù)慨丐,然后在set函數(shù)內(nèi)部,做相應(yīng)的邏輯處理泄私。
不過(guò)由于標(biāo)準(zhǔn)問(wèn)題房揭,F(xiàn)ireFox也有一套對(duì)應(yīng)的方法,defineGetter()和defineSetter()晌端。用這兩個(gè)方法重寫上面的例子可以這樣寫:

let person = {
  year: 4,
  edition: 1
}
person._defineGetter_('year', function() {
  return this.year
})
person._defineSetter_('year', function(newValue) {
  if(newValue > 4) {
    this.year = newValue
    this.edition += newValue - 4
  }
})

定義多個(gè)屬性

可以用Object.defineProperties()方法定義多個(gè)屬性捅暴。此方法接收兩個(gè)參數(shù),第一個(gè)是要添加或修改其屬性的對(duì)象咧纠,第二個(gè)對(duì)象的屬性與第一個(gè)對(duì)象中要添加或修改的屬性一一對(duì)應(yīng)蓬痒,也是一個(gè)描述符對(duì)象。
例如:

let person = {}
Object.defineProperties(person, {
  year: {
    writable: true,
    value: 4
  },
  edition: {
    writable: true,
    value: 1
  },
  _year: {
    get: function() {
      return this.year
    },
    set: function(newValue) {
      if(newValue > 4) {
        this._yaer = newValue
        this.edition += newValue - 4
       }
    }
  }
})

讀取屬性的特性

使用Object.getOwnPropertyDescriptor()方法可以讀取屬性對(duì)應(yīng)的特性漆羔。此方法接收兩個(gè)參數(shù)梧奢。第一個(gè)是屬性所在的對(duì)象,第二個(gè)是要讀取其描述符的屬性名稱钧椰。返回值是一個(gè)對(duì)象粹断,如果是數(shù)據(jù)屬性,則返回的對(duì)象包括configurable,enumerable,writablevalue這四個(gè)屬性嫡霞。如果是訪問(wèn)器屬性,則返回的對(duì)象包括configurable,enumerable,getset這四個(gè)屬性希柿。
如下例:

let book = {}
Object.getOwnPropertyDescriptor(book, {
  year: {
    value: 4
  },
  edition: {
    value: 1
  },
  _year: {
    get: function() {
      return this.year
    },
    set: function(newValue) {
      if(newValue > 4) {
        this.year = newValue
        this.edition += newValue - 4
      }
    }
  }
})
let obj = Object.getOwnPropertyDescriptor(person, 'year')
console.log(obj.value) // 4
console.log(obj.configurable) // false
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末诊沪,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子曾撤,更是在濱河造成了極大的恐慌端姚,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,265評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件挤悉,死亡現(xiàn)場(chǎng)離奇詭異渐裸,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)装悲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門昏鹃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人诀诊,你說(shuō)我怎么就攤上這事洞渤。” “怎么了属瓣?”我有些...
    開封第一講書人閱讀 156,852評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵载迄,是天一觀的道長(zhǎng)讯柔。 經(jīng)常有香客問(wèn)我,道長(zhǎng)护昧,這世上最難降的妖魔是什么魂迄? 我笑而不...
    開封第一講書人閱讀 56,408評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮惋耙,結(jié)果婚禮上极祸,老公的妹妹穿的比我還像新娘。我一直安慰自己怠晴,他們只是感情好遥金,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蒜田,像睡著了一般稿械。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上冲粤,一...
    開封第一講書人閱讀 49,772評(píng)論 1 290
  • 那天美莫,我揣著相機(jī)與錄音,去河邊找鬼梯捕。 笑死厢呵,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的傀顾。 我是一名探鬼主播襟铭,決...
    沈念sama閱讀 38,921評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼短曾!你這毒婦竟也來(lái)了寒砖?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,688評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤嫉拐,失蹤者是張志新(化名)和其女友劉穎哩都,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體婉徘,經(jīng)...
    沈念sama閱讀 44,130評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡漠嵌,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了盖呼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片儒鹿。...
    茶點(diǎn)故事閱讀 38,617評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖塌计,靈堂內(nèi)的尸體忽然破棺而出挺身,到底是詐尸還是另有隱情,我是刑警寧澤锌仅,帶...
    沈念sama閱讀 34,276評(píng)論 4 329
  • 正文 年R本政府宣布章钾,位于F島的核電站墙贱,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏贱傀。R本人自食惡果不足惜惨撇,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望府寒。 院中可真熱鬧魁衙,春花似錦、人聲如沸株搔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)纤房。三九已至纵隔,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間炮姨,已是汗流浹背捌刮。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留舒岸,地道東北人绅作。 一個(gè)月前我還...
    沈念sama閱讀 46,315評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像蛾派,于是被迫代替她去往敵國(guó)和親俄认。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容