1. 程式人生 > >js中物件屬性的型別和屬性的特性

js中物件屬性的型別和屬性的特性

ES5中物件的屬性可以分為資料屬性和訪問器屬性

  1. 資料屬性
    資料屬性包含以下4個特性:
    [[configurable]]:表示屬性是否可以被delete,是否可以被重新修改,或者是否可以被修改成訪問器屬性
    [[enumerable]]:是否可列舉,是否能通過for in 迴圈返回該屬性
    [[writable]]: 是否可修改
    [[value]]:屬性的資料值,預設是undefined
    資料屬性可以通過字面量形式直接定義(包括obj.proper),或者通過Object.defineProperty(obj)來定義,如:
var obj = {
	_name: 'zyp',
	_age: 18,
}
Object.defineProperty(obj, 'like', {
	value: 'sleep'
})

用Object.getOwnPropertyDescriptors(obj)可以獲取物件的所有屬性,包括屬性的特性。

var propers = Object.getOwnPropertyDescriptors(obj)
console.log('propers', propers)

輸出的結果見下圖,我們可以看到:通過字面量直接定義的資料屬性的[[configurable]]、[[enumerable]]、[[value]]三個特性值均預設為true;通過defineProperty()定義的資料屬性的[[configurable]]、[[enumerable]]、[[value]]三個特性值均預設為false。
在這裡插入圖片描述


2. 訪問器屬性(ie9+支援
訪問器屬性包含以下4個特性:

[[configurable]]:表示屬性是否可以被delete,是否可以被重新修改,或者是否可以被修改成訪問器屬性
[[enumerable]]:是否可列舉,是否能通過for in 迴圈返回該屬性
[[set]]:設定屬性值是訪問的函式。預設是undefined
[[get]]:讀取屬性值是訪問的函式。預設是undefined
訪問器屬性只能通過Object.defineProperty(obj)來進行定義,如:

Object.defineProperty(obj, 'name', {
	get: function() {
		return this._name
	},
	set: function(newVal) {
		this._name = newVal
	}
})
var propers = Object.getOwnPropertyDescriptors(obj)
console.log('propers', propers)

同樣,通過defineProperty()函式定義的訪問器屬性的[[configurable]]、[[enumerable]]兩個特性值均預設為false,如圖:
在這裡插入圖片描述

如果只定義了set特性或者只定義了get特性

Object.defineProperty(obj, 'age', {
	set: function(newVal) {
		this._age = newVal
	}
})
var propers = Object.getOwnPropertyDescriptors(obj)
console.log('propers', propers)
var age = obj.age //得到的age值為undefined

因此,在非嚴格模式下,如果只定義了set特性,那麼獲取得到該訪問器屬性的值為undefined, 嚴格模式下會報錯(高程上是這麼說的,但是實際在chrome控制檯中用’use strict’並沒有丟擲錯誤)。

接下來對資料屬性和訪問器屬性共有的configurable特性進行研究:
針對obj中的資料屬性_age和_name

  • _age屬性的configurable特性值為true,我們可以對其enumerable、writable、 value三個特性進行修改。
Object.defineProperty(obj, '_age', {
	enumerable: false,
	writable: false,
	value: 19
})
var propers = Object.getOwnPropertyDescriptors(obj)
console.log('propers', propers)

在這裡插入圖片描述
也可以將其修改為訪問器屬性,或者直接delete該屬性,這裡只演示delete操作。

delete obj._age
var propers = Object.getOwnPropertyDescriptors(obj)
console.log('propers', propers)

在這裡插入圖片描述

  • 我們將_name的configurable屬性為false後,我們只能將writable特性修改為false,不能修改其他特性,否則會報錯。
Object.defineProperty(obj, '_name', {
   	configurable: false
})
Object.defineProperty(obj, '_name', {
   	writable: false
})   //不報錯
Object.defineProperty(obj, '_name', {
   	value: 'zyp1'
})   

在這裡插入圖片描述
也不能進行delete操作(無效)。

delete obj._name

在這裡插入圖片描述

注意:資料屬性的特性和訪問器屬性的特性不能同時存在於一個屬性中。
參考:JavaScript高階程式設計(第3版) 6.1.1