JavaScript中对象的属性类型
JavaScript中,对象的属性有两种:数据属性和访问器属性。
数据属性
特性:
数据属性包括一个数据值的位置。在这个位置可以读取和写入值。数据属性有4个特性。
[[configurable]]:可配置。表示能否删除属性、能否修改属性的特性、能否把属性变为访问器属性。[[enumerable]]:可枚举。表示能否通过for-in循环进行遍历。[[writable]]:可写。表示能否修改属性的值。[[value]]:表示这个属性的数据值。
设置:
ES5提供了Object.defineProperty()方法,来设置属性的默认特性。该方法接收三个参数:属性所在对象、属性名字、属性描述符对象。其中,描述符对象用来设置configurable、enumerable、writable、value中的一个或多个值。
ES5也提供了Object.defineProperties方法,可以定义多个属性。
- 在设置了属性的特性后,任何尝试超过configurable或writable权限的操作,在非严格模式下将会被忽略,在严格模式下将会抛出错误。
- 一旦把属性定义为
configurable: false,就不能再变回configurable: true了。否则,无论是否处于严格模式,都会抛出TypeError错误。 - 例外:即便属性是
foncigurable: false,仍然可以把writable的状态由true改为false,但是无法由false改为true。
var person = {};
Object.defineProperty(person, 'name', {
configurable: false,
writable: false,
value: 'Nicholas'
});
// 测试:删除属性
delete person.name; // 由于configurable: false,删除失败
console.log(person.name); // Nicholas
// 测试:修改特性
Object.defineProperty(person, 'name', {
configurable: true
}); // 抛出错误:TypeError: Cannot redefine property: name
// 测试:修改属性的值
person.name = 'Greg'; // 由于writable: false,修改失败
console.log(person.name); // Nicholas
- 结合
configurable: false和writable: false,就可以创建一个真正的常量属性。 Object.seal()方法,会在一个现有对象上调用Object.preventExtensions(),并把所有属性标记为configurable: false。Object.freeze()方法,会在一个现有对象上调用Object.seal(),并把所有属性标记为writable: false。
读取:
ES5提供了Object.getOwnPropertyDescriptor()方法,来取得给定属性的描述符。该方法接收两个参数:属性所在对象、属性名字。返回值是一个对象,其属性有configurable、enumerable、writable、value。
还有一种区分枚举属性enumerable的方法是propertyIsEnumerable()。该方法不检查原型链。
- 在调用Object.defineProperty()方法时,如果不指定,configurable、enumerable、writable的默认值为false。
- 对于直接定义在对象上的属性,configurable、enumerable、writable的默认值为true,value的值为undefined。
// 使用Object.definedProperty设置的属性
var descriptor = Object.getOwnPropertyDescriptor(person, 'name');
console.log(descriptor.configurable); // false
console.log(descriptor.enumerable); // false
console.log(descriptor.writable); // false
console.log(descriptor.value); // Nicholas
// 直接定义在对象上的属性
var person2 = { name: "Greg" };
var descriptor2 = Object.getOwnPropertyDescriptor(person2, 'name');
console.log(descriptor2.configurable); // true
console.log(descriptor2.enumerable); // true
console.log(descriptor2.writable); // true
console.log(descriptor2.value); // Greg
// propertyIsEnumerable()方法
console.log(person.propertyIsEnumerable('name')); // false
console.log(person2.propertyIsEnumerable('name')); // true
关于可枚举属性
Object.keys(obj)会返回一个数组,包含所有可枚举属性。不检查原型链。Object.getOwnPropertyNames(obj)会返回一个数组,包含所有属性,无论是否枚举。不检查原型链。prop in obj会返回一个布尔值,判断对象的属性是否存在,无论是否枚举。检查原型链。obj.hasOwnProperty(prop)会返回一个布尔值,判断对象的指定属性是否存在,无论是否枚举。不会检查原型链。- 不可枚举的属性,不会出现在
for-in循环的遍历中。
var myObject = {};
Object.defineProperty(myObject, 'a', {
enumerable: true,
value: 2
});
Object.defineProperty(myObject, 'b', {
enumerable: false,
value: 3
});
// propertyIsEnumerable
console.log(myObject.propertyIsEnumerable('a')); // true
console.log(myObject.propertyIsEnumerable('b')); // false
// Object.keys()
console.log(Object.keys(myObject)); // ["a"]
// Object.getOwnPropertyNames()
Object.getOwnPropertyNames(myObject); // ["a", "b"]
// in操作符
console.log('a' in myObject); // true
console.log('b' in myObject); // true
console.log('toString' in myObject); // true
// hasOwnProperty()
console.log(myObject.hasOwnProperty('a')); // true
console.log(myObject.hasOwnProperty('b')); // true
console.log(myObject.hasOwnProperty('toString')); // false
// 遍历
for (var k in myObject) {
console.log( k, myObject[k] );
} // a 2
访问器属性
特性:
访问器属性有4个特性。对于访问器属性,JavaScript会忽略它们的writable和value特性,取而代之的该关心get和set属性。
[[configurable]]:表示能否删除属性、能否修改属性的特性、能否把属性变为访问器属性。[[enumerable]]:表示能否通过for-in循环进行遍历。直接定义在对象上的属性,默认值为true。[[get]]:读取属性时调用的函数。直接定义在对象上的属性,默认值为undefined。[[set]]:写入属性时调用的函数。直接定义在对象上的属性,默认值为undefined。
设置:
同样使用Object.defineProperty()方法和Object.defineProperties方法设置访问其属性。
- 不一定非要同时指定getter和setter函数。
- 只指定getter函数意味着属性不能写。尝试写入属性,在非严格模式下将会被忽略,在严格模式下将会抛出错误。
- 只指定setter函数意味着属性不能读。尝试读取属性,在非严格模式下将会返回undefined,在严格模式下将会抛出错误。
var book = {
_year: 2004,
edition: 1
};
Object.defineProperty(book, 'year', {
get: function() {
return this._year;
},
set: function(newYear) {
if (newYear > 2004) {
this._year = newYear;
this.edition += (newYear - 2004);
}
}
});
// 测试
book.year = 2005; // 注意:defineProperty中定义的属性名为year,而非_year
console.log(book.edition); // 2
另一种设置getter和setter函数的方法如下:
var myObject = {
// 定义getter
get foo() {
return 'You get: ' + this._foo_;
},
// 定义setter
set foo(val) {
this._foo_ = val;
}
}
// 测试
myObject.foo = 2;
console.log(myObject.foo); // You get: 2
读取:
同样使用Object.getOwnPropertyDescriptor()方法取得给定属性的描述符。
- 在调用Object.defineProperty()方法时,如果不指定,configurable、enumerable的默认值为false,get、set的默认值为undefined。
- 对于直接定义在对象上的属性,configurable、enumerable的默认值为true。
// 使用Object.definedProperty设置的属性
var descriptor = Object.getOwnPropertyDescriptor(book, 'year');
console.log(descriptor.configurable); // false
console.log(descriptor.enumerable); // false
console.log(typeof descriptor.get); // function
console.log(typeof descriptor.set); // function
// 直接定义在对象上的属性
var descriptor = Object.getOwnPropertyDescriptor(myObject, 'foo');
console.log(descriptor.configurable); // true
console.log(descriptor.enumerable); // true
console.log(typeof descriptor.get); // function
console.log(typeof descriptor.set); // function
参考:《JavaScript高级程序设计》、《你不知道的JavaScript(上卷)》
JavaScript中对象的属性类型的更多相关文章
- JavaScript中对象的属性
在JavaScript中,属性决定了一个对象的状态,本文详细的研究了它们是如何工作的. 属性类型 JavaScript中有三种不同类型的属性:命名数据属性(named data properties) ...
- 记录,javascript中对象的属性名是字符串,却可以不用引号
问题描述:今日看书,里面介绍js的对象的属性名是包括空字符串在内的所以字符串 问题来了,我们平时定义的对象如下,是没有引号""or’'的 var someone = { f ...
- javascript中对象的属性的特性
1.ES5的属性特性包括下面六个: configurable: 表示能否通过delete来删除属性从而重新定义属性,能够修改属性的特性,默认为true enumberable: 表示是否能通过for- ...
- JavaScript中对象的属性:如何遍历属性
for/in 语句循环遍历对象的属性. js中获取key得到某对象中相对应的value的方法:obj.key js中根据动态key得到某对象中相对应的value的方法有二: 一.var key = & ...
- javascript中对象字面量的理解
javascript中对象字面量与数组字面量 第一部分 我们知道JavaScript中的数据类型有基本数据类型和引用类型,其中Object类型就是非常常用的类型.那么如果创建一个Object类型的实例 ...
- 关于JavaScript中对象的继承实现的学习总结
一.原型链 JavaScript 中原型链是实现继承的主要方法.其主要的思想是利用原型让一个引用类型继承另一个引用类型的属性和方法.实现原型链有一种基本模式,其代码如下. function Super ...
- javascript中对象的深度克隆
记录一个常见的面试题,javascript中对象的深度克隆,转载自:http://www.2cto.com/kf/201409/332955.html 今天就聊一下一个常见的笔试.面试题,js中对象的 ...
- Javascript中对象的Obeject.defineProperty()方法-------------(ES5/个人理解)
在讲到Obeject.defineProperty()方法之前先得说明一下ECMAScript中有两种属性:数据属性和访问器属性. 两种属性存在的意义:描述对象属性(key)的一些特性,因为这些属性是 ...
- C#保留2位小数几种场景总结 游标遍历所有数据库循环执行修改数据库的sql命令 原生js轮盘抽奖实例分析(幸运大转盘抽奖) javascript中的typeof和类型判断
C#保留2位小数几种场景总结 场景1: C#保留2位小数,.ToString("f2")确实可以,但是如果这个数字本来就小数点后面三位比如1.253,那么转化之后就会变成1.2 ...
随机推荐
- 【BZOJ 3569】DZY Loves Chinese II 随机化+线性基
用到一个结论——[先建树,再给每个非树边一个权值,每个树边的权值为覆盖他的非树边的权值的异或和,然后如果给出的边存在一个非空子集异或和为0则不连通,否则连通](必须保证每条边的出现和消失只能由自己产生 ...
- Linux之同步互斥阻塞20160703
主要介绍一下Linux下的互斥与阻塞方面的知识: 1. 原子操作 原子操作指的是在执行过程中不会被别的代码路径所中断的操作. 常用原子操作函数举例: atomic_t v = ATOMIC_INIT( ...
- halcon程序输出成c++程序
halcon语法程序: dev_open_window (0, 300, -1, -1, 'black', WindowID) read_image (Die4, 'C:/Users/Public/D ...
- POJ---3463 Sightseeing 记录最短路和次短路的条数
Sightseeing Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 9247 Accepted: 3242 Descr ...
- SDUT3926 kmp
bLue的二叉树 Time Limit: 3000MS Memory Limit: 65536KB Submit Statistic Problem Description Keke 是一个喜爱种树的 ...
- 如何更有效使用 Rational AppScan 扫描大型网站,第 1 部分: 工作原理及技术分析
Rational AppScan 工作原理 Rational AppScan(简称 AppScan)其实是一个产品家族,包括众多的应用安全扫描产品,从开发阶段的源代码扫描的 AppScan sourc ...
- 2017 济南综合班 Day 7
a 两个指针L.R R开始指向恰好[R,n]有不超过k个逆序对的地方 随着L的右移,R指针只会右移 逆序对有2部分 1.L左侧与其他位置形成的逆序对 2.R右侧与其他位置形成的逆序对 用树状数组分别 ...
- Dungeon Master(三维bfs)
题目链接:http://poj.org/problem?id=2251 题目: Description You are trapped in a 3D dungeon and need to find ...
- 最短路之spfa系列
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2544 Problem Description 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t ...
- 如何免费上传4G以上大文件至百度云网盘
百度云网盘的容量高达2048G,因而如今使用百度云网盘的用户也越来越多, 但是百度云中如果要上传超过4G的大文件,必须要升级VIP才行,但这需要收费.那么,超过4G以上的大文件我们该怎样上传到百度云呢 ...