# 对象属性
# 二、属性类型
# 1. 数据属性
数据属性包含一个数据值的位置。四个特性
[[Configurable]]
可配置,定义能否 删除属性,修改属性特性,或修改未访问器属性,默认值 true[[Enumerable]]
可否通过 for-in 循环返回属性,默认值 true[[Writable]]
能否修改属性的值,默认值 true[[Value]]
包含这个属性的数据值,默认值 undefined
// 修改属性默认的特性,必须使用 Object.defineProperty(所在对象, 属性名, 描述符对象)
var person = {}
Object.defineProperty(person, 'name', {
writable: false,
value: 'myName'
})
// Configurable 决定了,能否 delete 属性
Object.defineProperty(person, 'name', {
Configurable: false,
value: 'myName2'
})
通过定义 writable 为 false,如果企图再次通过 Object.defineProperty
来定义 value
值会报错:
Cannot redefine property: name
# 2. 访问器属性
包含一对儿 getter setter 函数,四个特性
[[Configurable]]
: 配置,可否修改属性的特性。默认 true[[Enumerable]]
: 可否通过 for-in 遍历[[Get]]
: 读取属性时调用的函数,默认 undefined[[Set]]
: 写入属性时调用的函数,默认 undefined
var book = {
_year: 2004, //表示此属性,仅被对象的方法修改,不要通过 book._year = xxx 的方式从外部赋值
edition: 1
}
Object.defineProperty(book, "abc", {
get: function() {
return this._year
},
set: function(newValue) {
if(newValue > 2004) {
this._year = newValue
this.edition += this._year - 2004
}
}
})
book.abc = 2005 // 某一个属性变化,导致其他属性变化
console.log(book.edition)
# 三、属性特性的定义与获取
# 3. 一次定义多个属性
Object.defineProperties(对象, 修改属性的对象)
var book = {}
Object.defineProperties(book, {
_year: {
value: 2004
},
edition: {
value: 1
},
year: {
get: function() {
return this._year
},
set: function(newValue) {
if(newValue > 2004) {
this._year = newValue
this.edition += newValue - 2004
}
}
},
})
# 4. 需要注意对象的创建方式不同,默认属性的差异
字面量形式
var book = { _year: 1212 } console.log(Object.getOwnPropertyDescriptor(book, "_year")) /* { value: 1212, writable: true, enumerable: true, configurable: true } */
Object.defineProperty 创建
var book = {} Object.defineProperty(book, _year, { value: 1212 }) /* { value: 1212, writable: false, enumerable: false, configurable: false } */
# 5. 一个属性,要么是 数据属性
,要么是 访问器属性
,二者不可兼得
let book = {}
Object.defineProperty(book, 'year', {
get: function() {
return this._year
},
set: function(newValue) {
this._year = newValue
},
value: 2222
})
console.log(Object.getOwnPropertyDescriptor(book, 'year'))
// 报错 Invalid property descriptor.
// Cannot both specify accessors and a value or writable attribute.
- 在 es6 中块级作用域,里 有 var 变量,依然外部可以读取,let 变量 不可以
- Object.getOwnPropertyDescriptor(obj, props) 可针对所有对象使用,获取属性特性
# 疑问
String.prototype.lengthByte 拓展了 String 对象的方法,但为何必须调用时执行,而直接加在方法后执行就是0
str.lengthByte() //可行
String.prototype.lengthByte = function() {
}() //不可行
# 其他知识
javascript 的每个对象都有 __proto__
属性,但是只有函数对象有 prototype
属性。
__proto__
表示该函数对象的原型- prototype表示使用new来执行该函数时(这种函数一般成为构造函数,后面会讲解),新创建的对象的原型。例如:
var d = new Date();
d.__proto__ === Date.prototype; //这里为true
Date.__proto__ === Object.__proto__ //这里为true
需要注意的是,这里的arguments不是一个数组,它只是一个有length属性的类数组对象(Array-like),它并不拥有数组的其他方法。
字面量(Array Literal) 的含义?