欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

js?通過Object.defineProperty()?定義和控制對象屬性

 更新時間:2022年08月03日 10:40:32   作者:亦黑迷失  
這篇文章主要介紹了js?通過Object.defineProperty()?定義和控制對象屬性,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的朋友可以參考一下

Object.defineProperty()

Object.defineProperty() 用于給一個對象定義一個新屬性或是修改某個現(xiàn)有屬性,并返回此對象,事實上就算不定義變量去接收返回值,該對象也會被直接修改(所以它不是一個純函數(shù))。它接收 3 個參數(shù),第 1 個是要定義屬性的對象;第 2 個是要定義或修改的屬性的屬性名或 Symbol;第 3 個是對該屬性的描述,稱之為屬性描述符,為一個對象,可以擁有 4 個 key。

屬性描述符

屬性描述符可以分為 2 類——數(shù)據(jù)屬性描述符存取屬性描述符,它們有 2 個共同的可擁有的 key: configurable 和 enumerable。區(qū)別在于剩下 2 個,數(shù)據(jù)屬性描述符為 value 和 writable 而存儲屬性描述符為 get 和 set。

下圖截取自 MDN 文檔:

一個屬性如果擁有了 value 或 writable,那么它就是數(shù)據(jù)描述符,它就不能同時擁有 get 或 set;反之,如果擁有了 get 或 set,那么它就是存取描述符,同理不能再擁有 value 或 writable。 接下來詳細介紹下上圖中的 6 個特性:

configurable

描述該屬性是否可以被刪除

'use strict'
const obj = { singer: 'Jay' }
Object.defineProperty(obj, 'singer', {
  configurable: false
})
delete obj.singer

我們將 obj 的 singer 屬性的 configurable 設(shè)置為了 false,所以在第 6 行使用 delete 刪除 singer 屬性時,在嚴格模式下(在非嚴格模式下不會報錯,但也不會刪除 singer,即靜默失?。?,瀏覽器會報錯:

2. 描述該屬性是否可以再次通過 Object.defineProperty() 來修改屬性描述:

const obj = { singer: 'Jay' }
Object.defineProperty(obj, 'age', {
  configurable: false
})
Object.defineProperty(obj, 'age', {
  enumerable: flase
})

當(dāng)我們將 age 的 configurable 設(shè)為 false 后,在第 6 行試圖修改 age 的 enumerable 特性,會報錯“TypeError: Cannot redefine property: age”。當(dāng)設(shè)置 configurable 為 false 后(writable 默認為 false),該屬性的任意描述符(enumerable,value 或是 get、set)都不能被改變了。但是,如果初始定義時 writable 為 true,即使 configurable 為 false,那么接下去還是可以將 writable 改為 false,同時也可以修改 value:

const obj = new Object()
obj.singer = 'Jay'
Object.defineProperty(obj, 'age', {
  configurable: false,
  writable: true
})
console.log(obj.age) // undefined
Object.defineProperty(obj, 'age', {
  writable: false,
  value: 40
})
console.log(obj.age) // 40

注:上面采用了 new Object() 的方式定義了一個對象,和直接通過字面量定義對象作用一樣。

描述該屬性是否可以修改屬性描述符類型:

const obj = { singer: 'Jay' }
Object.defineProperty(obj, 'singer', {
  configurable: false
})
Object.defineProperty(obj, 'singer', {
  get() {
    return 'Zhou'
  }
})

上面這個例子里,在第 1 行我們通過字面量的方式直接定義了 obj 對象,其屬性 singer 的描述符默認為數(shù)據(jù)描述符,在第 3 行我們將其的 configurable 設(shè)為 false,然后在第 6 行給它定義一個 getter 函數(shù),也就是試圖將它改為存取描述符,瀏覽器同樣會報 "Cannot redefine property: singer" 錯誤。 如果我們新定義一個 age 屬性,讓其的屬性描述符為存取描述符,但是 configurable 依舊設(shè)置為 false:

const obj = { singer: 'Jay', _age: 40 }
Object.defineProperty(obj, 'age', {
  configurable: false,
  enumerable: true,
  get() {
    return this._age
  },
  set(val) {
    this._age = val
  }
})
Object.defineProperty(obj, 'age', {
  value: 35
})

那么我們想再次給 age 的屬性描述符一個 value 特性,想將之改為數(shù)據(jù)描述符,瀏覽器也會報錯。

enumerable

描述該屬性是否是可枚舉的。比如現(xiàn)在有如下代碼,我們通過 Object.defineProperty() 給 obj 定義 age 屬性, 并設(shè)置 enumerable 為 false:

var obj = { singer: 'Jay' }
Object.defineProperty(obj, 'age', {
  enumerable: false
})

現(xiàn)在,當(dāng)我使用 for in 遍歷 obj 時,只能得到 singer 而得不到 age,因為 for in 是以任意順序遍歷 obj 的除 Symbol 以外的可枚舉屬性(包括原型上的屬性):

for (const key in obj) {
  console.log(key) // singer
}

使用 Object.keys() 遍歷得到的數(shù)組也只包含 singer,因為 Object.keys() 返回的是 obj 自身的可枚舉屬性組成的數(shù)組:

console.log(Object.keys(obj)) // ['singer']
復(fù)制代碼

如果是直接打印 obj 對象,那么在 Node.js 中運行將看不到 age,在 Chrome 瀏覽器中可以看到,但是 age 是淺色的:

如果想查看一個 enumerable 為 false 的屬性(比如 obj 的 age 屬性),除了可以直接通過 obj.age 查看,還可以通過 Object.getOwnPropertyNames()——返回自身除 Symbol 值作為名稱的屬性之外的所有屬性,或是 Reflect.ownKeys()——獲取自身所有的屬性:

console.log(Object.getOwnPropertyNames(obj)) // [ 'singer', 'age' ]
console.log(Reflect.ownKeys(obj)) // [ 'singer', 'age' ]

writable

數(shù)據(jù)描述符專有特性,描述屬性是否可修改。

'use strict'
var obj = { singer: 'Jay' }
Object.defineProperty(obj, 'singer', {
  writable: false
})
obj.singer = 10

上例中,在嚴格模式下,在第 6 行給 writable 為 false 的屬性 singer 賦值,會報錯 “TypeError: Cannot assign to read only property 'age' of object '#'”。在非嚴格模式下不會報錯,但也不會修改屬性 singer 的值。 另外,通過前面的例子可以看出,writable 的優(yōu)先級是高于 configurable 的。

value

數(shù)據(jù)描述符專有特性,為屬性的值。讀取屬性時返回該值;修改屬性時則修改該值。

get

當(dāng)屬性被獲取時,會執(zhí)行 getter 函數(shù)。

set

當(dāng)屬性被設(shè)置時,會執(zhí)行 setter 函數(shù)。

const obj = { singer: 'Jay', _age: 40 }
Object.defineProperty(obj, 'age', {
  get() {
    return this._age
  },
  set(value) {
    this._age = value
  }
})
console.log(obj.age) // 40
obj.age = 50
console.log(obj.age) // 50

用存取描述符定義的屬性,直接打印查看對象時,比如我們將上例中 obj 的 age 屬性的 enumerable 設(shè)為 true,然后 console.log(obj),會發(fā)現(xiàn)其結(jié)果為“{ singer: 'Jay', _age: 40, age: [Getter/Setter] }” 。 順便說一句,vue2 的響應(yīng)式原理就用到了 getter 和 setter,具體可前往《vue.js數(shù)據(jù)響應(yīng)式原理解析》。

默認值

直接給對象定義屬性時:

  • configurable 默認為 true;
  • enumerable 默認為 true;
  • writable默認為 true;
  • value 默認為定義時賦的值;
  • get 默認為 undefined;
  • set 默認為 undefined;

通過屬性描述符定義一個屬性時:

  • configurable 默認為 false;
  • enumerable 默認為 false;
  • writable默認為 false;
  • value 默認為 undefined;
  • get 默認為 undefined;
  • set 默認為 undefined;

獲取屬性的描述符

如果想要驗證上面的結(jié)論,我們可以通過 Object.getOwnPropertyDescriptor(對象, '屬性名') 查看某個對象自有屬性的屬性描述符,或是 Object.getOwnPropertyDescriptors(對象) 查看某個對象的所有的自身屬性的屬性描述符。

Object.defineProperties()

Object.defineProperty() 是一次定義 / 修改一個屬性,傳入 3 個參數(shù)。如果我們想一次性通過屬性描述符定義 / 修改多個屬性,可以使用 Object.defineProperties(),它傳入 2 個參數(shù),第 1 個參數(shù)為要定義屬性的對象;第二個參數(shù)為一個對象,其鍵名為要定義的屬性,鍵值為一個對象,里面就是關(guān)于該屬性的屬性描述符定義。

比如:

const obj = { singer: 'Jay', _age: 40 }
Object.defineProperties(obj, {
  age: {
    configurable: true,
    enumerable: true,
    get() {
      return this._age
    },
    set(val) {
      this._age = val
    }
  },
  gender: {
    configurable: true,
    enumerable: true,
    writable: true,
    value: '男'
  }
})

對象本身的兩個方法

其實每個對象本身都可以直接使用 getter —— 得到當(dāng)前屬性值的回調(diào)函數(shù),和 setter —— 監(jiān)視當(dāng)前屬性值變化的回調(diào)函數(shù),來定義屬性,比如:

const obj = {
  firstName: 'Jay',
  lastName: 'Zhou',
  get fullName() {
    return this.firstName + ' ' + this.lastName
  },
  set fullName(val) {
    const tempArr = val.split(' ')
    this.firstName = tempArr[0]
    this.lastName = tempArr[1]
  }
}

到此這篇關(guān)于js 通過Object.defineProperty() 定義和控制對象屬性的文章就介紹到這了,更多相關(guān)js Object.defineProperty內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • js 中rewrap-ajax.js插件實例代碼

    js 中rewrap-ajax.js插件實例代碼

    這篇文章主要介紹了rewrap-ajax.js插件,需要的朋友可以參考下
    2017-10-10
  • JS添加刪除一組文本框并對輸入信息加以驗證判斷其正確性

    JS添加刪除一組文本框并對輸入信息加以驗證判斷其正確性

    需要添加幾組數(shù)據(jù)到數(shù)據(jù)庫,但是具體幾組數(shù)據(jù)不確定,有客戶來填寫,所以,這里我用JS進行添加刪除子方案,并要對方案輸入的正確性加以判斷,感興趣的朋友可以了解下
    2013-04-04
  • 原生js實現(xiàn)跨瀏覽器獲取鼠標按鍵的值

    原生js實現(xiàn)跨瀏覽器獲取鼠標按鍵的值

    e.button W3C是獲取鼠標按鍵 0 表示左鍵 1表示中鍵 2表示右鍵 而IE瀏覽器則是 1表示左鍵 4表示中間 2表示右鍵 這里的IE瀏覽器主要是IE8以下的瀏覽器,感興趣的朋友可以參考下哈
    2013-04-04
  • JavaScript判斷變量是否為數(shù)組的方法(Array)

    JavaScript判斷變量是否為數(shù)組的方法(Array)

    這篇文章主要介紹了JavaScript判斷變量是否為數(shù)組的方法(Array),涉及到j(luò)avascript 數(shù)組 變量相關(guān)知識,感興趣的朋友一起學(xué)習(xí)吧
    2016-02-02
  • js匿名函數(shù)的調(diào)用示例(形式多種多樣)

    js匿名函數(shù)的調(diào)用示例(形式多種多樣)

    匿名函數(shù)就是沒有實際名字的函數(shù),javaScript的匿名函數(shù)形式多樣,下面就一一為大家羅列出來
    2014-08-08
  • js禁止瀏覽器頁面后退功能的實例(推薦)

    js禁止瀏覽器頁面后退功能的實例(推薦)

    下面小編就為大家?guī)硪黄猨s禁止瀏覽器頁面后退功能的實例(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • 如何在JavaScript中設(shè)置定時器

    如何在JavaScript中設(shè)置定時器

    在?JavaScript?中,設(shè)置定時器通常使用兩個內(nèi)置的函數(shù):setTimeout()?和?setInterval(),本文將結(jié)合實際項目代碼為大家講解一下如何使用它們
    2024-12-12
  • js實現(xiàn)簡單廣告小窗口

    js實現(xiàn)簡單廣告小窗口

    這篇文章主要為大家詳細介紹了js實現(xiàn)簡單廣告小窗口,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • JS使用Promise時常見的5個錯誤總結(jié)

    JS使用Promise時常見的5個錯誤總結(jié)

    Promise?提供了一種優(yōu)雅的方法來處理?JS?中的異步操作。這也是避免“回調(diào)地獄”的解決方案。然而,并沒有多少開發(fā)人員了解其中的內(nèi)容。因此,許多人在實踐中往往會犯錯誤。在本文中,介紹一下使用?promise?時的五個常見錯誤,希望大家能夠避免
    2022-11-11
  • JS作用域鏈詳解

    JS作用域鏈詳解

    這篇文章主要為大家詳細介紹了JS作用域鏈的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-06-06

最新評論