JavaScript 学习笔记 (3) - 对象的属性

区分对象实例自身属性还是原型属性

有什么区别呢?对象自身的属性可以访问 (读),也可以设置(写)。而原型的属性,则只能读不能写。如果使用赋值语句对原型的属性赋值,则在对象实例中新建的一个同名属性,这个同名属性屏蔽了原型属性。比如,定义一个简单的对象:

var o = {x:1, y:2};

如果设置 o.x = 10;,此时,o.x 的值为 10。这个时候对象 o 变为:{x:10, y:2}。与之相比较,我们定义另外一个对象 p

var p = {y:2};
p.__proto__.x = 1;
// 设置 p 的属性 x
p.x = 10;

此时查看 p.x ,属性值也为 10,但其实对象 p是新建了一个同名属性 x,原型中属性 x 的值仍为 1:

遍历对象的属性

使用 for / in 可以枚举对象中可访问的可枚举的 (enumerable) 属性。通过代码定义的属性都是可枚举的。

var o = {x:1, y:2, z:3};
o.__proto__.w = 10;
for (var prop in o) {
	console.log(prop);
}

打印出对象 o 的四个属性 (x、y、z、w)

检测对象是否含有某个属性

  1. in 可以检测到对象实例自身的属性,以及继承的属性:
var o = {x:1, y:2, z:3};
console.log('x' in o); // 返回 true,因为 o 含有 x 属性
console.log('y' in o); // 返回 false,因为 o 不含有 y 属性
console.log('toString' in o); // 返回 true,因为 o 继承自 object, object 含有 toString 属性
  1. hasOwnProperty 用于检测对象实例是否含有自身的属性
var o = {x:1, y:2, z:3};
console.log(o.hasOwnProperty('x')); // 返回 true
console.log(o.hasOwnProperty('w')); // 返回 false
console.log(o.hasOwnProperty('toString'));  // 返回 false
  1. 在 JavaScript 中,访问对象实例不存在的属性不会返回错误,而是返回 undefined。可以利用这一特性来检测是否对象实例含有某属性 (即可以判断有,而不能判断是否没有)。
var o = {x:1, y:2, z:3};
console.log(o.x !== undefined);  // 返回 true
console.log(o.w !== undefined);  // 返回 false
console.log(o.toString !== undefined);  // 返回 true

数据属性和访问器属性

数据属性

JavaScript 有两种属性:数据属性和访问器属性。比如我们定义 person 对象:

var person = {name: 'Alice'};

name 属性就是一个数据属性。数据属性有四个描述其行为的特性

  • [[Configurable]]: 定义是否能通过 delete 语句删除属性从而重新定义属性,是否可以修改属性的特性,是否可以把属性修改为访问器属性。该特性的默认值为 true;

  • [[Enumerable]]: 能否遍历 (即通过 for/in 来循环),该特性的默认值为 true;

  • [[Writable]]: 能否修改属性的值,如果这个特性为 false,则属性是只读的。该特性默认值为 true;

  • [[Value]]: 内部管理属性的值,比如 name 属性的值。该特性的默认值为 undefined;

这四个属性不能在 JavaScript 代码中直接访问它们,必须时候用 ES5 的 Ojbject.defineProperty() 方法来修改。

// 定义一个只读属性
var person = {};
Object.defineProperty(person, "name", {
    writable: false,
    value: "Brown"
});

// 尝试修改一个只读属性
// 在严格模式下,会导致抛出错误,在非严格模式下,赋值被忽略
person.name = "Bruce";
console.log(person.name);

访问器属性

访问器属性指通过 getset 函数定义的特性。比如:

var book = {
    name: "Professional JavaScript",
    __year: 2010
};

// 定义 year 属性,最小值为 2010
Object.defineProperty(book, "year", {
    get: function() {
        return this.__year;
    },
    set: function(newValue) {
        if (newValue > 2010){
            this.__year = newValue;
        }
    }
})

如果用大于 2010 的值对 year 属性赋值,year 属性将被修改,如果用小于 2010 的值对 year 属性赋值,year 属性不被修改。

book.year = 2005;
console.log(book.year);  // 返回 2010

访问器属性有四个特性:

  • [[Configurable]]: 同数据属性的特性;
  • [[Enumerable]]: 同数据属性的特性;
  • [[Get]]: 读取属性时调用的函数;
  • [[Set]]: 写入属性时调用的函数。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值