这是《JavaScript高级程序设计(第三版)》第六章相关内容的总结。

ECMAScript中有两种属性:数据属性和访问器属性。每种属性都有四个特性值。

数据属性的四个特性值:

[[Configurable]]:表示能否通过delete删除属性;能否修改属性的特性值;能否把属性修改为访问器属性。直接在对象上定义的属性,该特性的默认值为true。

[[Enumerable]]:表示能否通过for-in循环返回属性。直接在对象上定义的属性,该特性的默认值为true。

[[Writable]]:表示能否修改属性的值。直接在对象上定义的属性,该特性的默认值为true。

[[Value]]:包含这个属性的数据值。读取属性值的时候。从这个位置读;写入属性值的时候,把新值保存在这个位置。该特性的默认值为undefined。

访问器属性的四个特性:

访问器属性只能通过相应的方法设置,不能在对象上直接设置。

[[Configurable]]:表示能否通过delete删除属性;能否修改属性的特性值;能否把属性修改为数据属性。

[[Enumerable]]:表示能否通过for-in循环返回属性。

[[Get]]:在读取属性时调用的函数。该特性的默认值为undefined。

[[Set]]:在写入属性时调用的函数。该特性的默认值为undefined。

ECMAScript 5中操作属性特性的方法有3个:

Object.defineProperty():该方法用来设置单个属性的特性。它接收三个参数:属性所在的对象、属性的名字和一个描述符对象。其中描述符对象的属性必须是:configurable、enumerable、writable、value、get、set中的一个或多个。当然要根据属性类型选择。

Object.defineProperties():这个方法是上一个方法的增强版,可以同时设置多个属性的特性。它接收两个对象参数:第一个对象是要添加和修改其属性的对象,第二个对象的属性与第一个对象中要添加或修改的属性一一对应(通过例子看,一目了然)。

Object.getOwnPropertyDescriptor():这个方法返回一个描述符对象,可以取得给定属性的特性的值。它接收两个参数:属性所在的对象和要读取其特性的属性名称。如果是数据属性,返回的对象有configurable、enumerable、writable、value四个属性;如果是访问器属性,返回的对象有configurable、enumerable、get、set四个属性。

例1

 <script type="text/javascript">
var a = {
name: 'A',
type: 'object'
}
//修改直接在对象上定义的属性的值
Object.defineProperty(a,'type',{
value: 'car'
});
//用Object.defineProperty()方法给对象添加属性
Object.defineProperty(a,'style',{
value: 'no'
});
//设置访问器属性
Object.defineProperty(a,'country',{
get: function() {
return 'none';
}
}); var b = Object.getOwnPropertyDescriptor(a,'type');
alert(b.configurable);//true
alert(b.enumerable);//true
alert(b.writable);//true var c = Object.getOwnPropertyDescriptor(a,'style');
alert(c.configurable);//false
alert(c.enumerable);//false
alert(c.writable);//false var d = Object.getOwnPropertyDescriptor(a,'country');
alert(a.country);//none
alert(d.configurable);//false
alert(d.enumerable);//false
alert(d.set);//undefined
alert(d.get);//输出get后面完整的匿名函数
</script>

通过上面的例子可以看到,用Object.defineProperty()方法给对象添加新属性,该属性的未指定的特性值要么默认为false,要么默认(set)为undefined,说明用Object.defineProperty()方法添加的新属性除非明确设置,否则一旦设置完成后是不可配置和更改的。而原本直接定义在对象上的属性,用Object.defineProperty()方法修改,未指定的特性值仍然默认为true,还是可以配置和更改的。

例2

 var a = {
name: 'A',
type: 'object'
}
//修改直接在对象上定义的属性的值
Object.defineProperty(a,'type',{
configurable: false,
value: 'car'
}); delete a.type;
var b = Object.getOwnPropertyDescriptor(a,'type'); console.log(a.type);//car
console.log(b.configurable);//false Object.defineProperty(a,'type',{
configurable: true
});

上面代码在火狐的Firebug中会报错:

意思就是说,一旦把configurable设置为false,就改不回来了。书上说,此时再调用Object.defineProperty()方法修改除writable的特性,都会导致错误。但是,我觉得这要根据这个属性是怎么添加到对象上的来区分。

先看直接在对象上直接定义的属性:

 var a = {
name: 'A',
type: 'object'
}
//修改直接在对象上定义的属性的值
Object.defineProperty(a,'type',{
configurable: false,
value: 'car'
}); console.log(a.type);//car
console.log(b.configurable);//false Object.defineProperty(a,'type',{
writable: false,
value: 'to'
}); var b = Object.getOwnPropertyDescriptor(a,'type');
console.log(b.value);//to
console.log(b.writable);//false
console.log(a.type);//to

输出结果:

再调用Object.defineProperty()方法修改除writable的特性(这里修改了value的值),没有导致错误,而且还修改成功了(当然修改enumerable的值还是会导致错误的)。

再来看通过调用Object.defineProperty()方法添加的属性:

 var a = {
name: 'A',
type: 'object'
}
//修改直接在对象上定义的属性的值
Object.defineProperty(a,'style',{
configurable: false,
value: 'jiangnan'
});
var b = Object.getOwnPropertyDescriptor(a,'style');
console.log(a.style);//jiangnan
console.log(b.configurable);//false Object.defineProperty(a,'style',{
writable: true,
value: 'to'
});

看运行结果:

再调用Object.defineProperty()方法修改writable的特性,导致错误。

下面看Object.defineProperties()方法的用法:

 var a = {};
Object.defineProperties(a,{
name: {
value: 'A'
//其余的三个特性未明确指定,默认值为false
},
type: {
get: function() {return 'object'}
//set未指定,默认为undefined
//其余两个特性默认为false
}
});
console.log(a.type);//object
var b = Object.getOwnPropertyDescriptor(a,'name'); console.log(b.writable);//false Object.defineProperty(a,'name',{
writable: true,
});

运行结果:

以上就是关于对象属性特性的内容。

ECMAScript 5中属性的特性值的更多相关文章

  1. ECMAScript 6中的数组操作方法

    本文介绍ECMAScript 6即将带给我们新的数组操作方法,以及在怎样在现有浏览器应用这些新的数组特性. Note: 我将使用交替使用构造器(constructor)和类(class)两个术语. 类 ...

  2. JavaScript数据结构与算法(八) 集合(ECMAScript 6中定义的类似的Set类)

    TypeScript方式实现源码 // 特性: // 1. 集合是由一组无序且唯一(即不能重复)的项组成的.这个数据结构使用了与有限集合相同的数学概念,但应用在计算机科学的数据结构中. // 2. 也 ...

  3. js中属性类型:数据属性与访问器属性

    js中属性类型分为两种:数据属性和访问器属性 在js中,对象都是由名值对构成的,名:就是我们所说的属性名,值就是属性对应的值(基本值.对象.方法). ECMA-262第5版定义了只有内部才用的特性,描 ...

  4. ECMAScript 5中对Array中新增了9个方法

    ECMAScript 5中对Array中新增了9个方法: 5个迭代方法(循环操作数组中的各个项):forEach(),map(),filter(),every()和some() 2个归并方法(迭代数组 ...

  5. VB类模块中属性的参数——VBA中Range对象的Value属性和Value2属性的一点区别

    在VB中,属性是可以有参数的,而VBA中属性使用参数非常常见.比如最常用的:Worksheet.Range("A1:A10")  VB的语法,使用参数的不一定是方法,也有可能是属性 ...

  6. ECMAScript 6中的let和const关键词

    ECMAScript 6中多了两个定义变量的关键词,一个是let,另一个是const,后者顾名思义就是常量定义,前者的作用域范围是块级的. 一般写过js的童鞋都知道,同其他语言一样,JS中的变量作用域 ...

  7. ECMASCRIPT 6中字符串的新特性

    本文将覆盖在ECMAScript 6 (ES6)中,字符串的新特性. Unicode 码位(code point)转义 Unicode字符码位的长度是21位[2].而JavaScript的字符串,是1 ...

  8. [原创]java WEB学习笔记48:其他的Servlet 监听器:域对象中属性的变更的事件监听器 (3 个),感知 Session 绑定的事件监听器(2个)

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  9. 为什么Nhibernate中属性和方法必须Virtual的

    如果你曾经用过NHibernate 2.0或者更高的版本,那您一定碰到过下面的错误:NHibernate.InvalidProxyTypeException: The following types ...

随机推荐

  1. Windows驱动开发技术详解HelloWDM例子win7下无法安装

    HelloWDM例子编译完成之后,在win7下安装显示 查看setupapi.dev看到如下信息 这个C:\MyDriver_Check目录完全不是我指定的,我放到c盘根目录下 查看inf [Sour ...

  2. Eclipse自动生成作者、日期注释等功能设置

    我们在使用Eclipse 编写Java代码时,自动生成的注释信息都是按照预先设置好的格式生成的. 修改作者.日期注释格式:打开Windows->Preferences->Java-> ...

  3. maven filter 乱码,MalformedByteSequenceException: Invalid byte 3 of 3-byte UTF-8 sequence.

    <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactI ...

  4. 手机CPU和GPU厂商

    CPU: 1.苹果 (Apple) A系列 ARM授权,基于Cortex-A系列架构 A5基于Cortex-A9架构,双核,主频800M-1Ghz,内存双通道32bitLPDDR2,GPU采用Powe ...

  5. Javascript基础回顾 之(三) 面向对象

    本来是要继续由浅入深表达式系列最后一篇的,但是最近团队突然就忙起来了,从来没有过的忙!不过喜欢表达式的朋友请放心,已经在写了:) 在工作当中发现大家对Javascript的一些基本原理普遍存在这里或者 ...

  6. Python黑帽编程2.1 Python编程哲学

    Python黑帽编程2.1  Python编程哲学 本节的内容有些趣味性,涉及到很多人为什么会选择Python,为什么会喜欢这门语言.我带大家膜拜下Python作者的Python之禅,然后再来了解下P ...

  7. CoffeeScript实现Python装潢器

    在上篇Angular遇上CoffeeScript – NgComponent封装中,我们讲述了CoffeeScript这门小巧的语言,摒弃JavaScript中糟粕(“坑”)部分,并将JavaScri ...

  8. Android开发学习之路-该怎么学Android(Service和Activity通信为例)

    在大部分地方,比如书本或者学校和培训机构,教学Android的方式都基本类似,就是告诉先上原理方法,然后对着代码讲一下. 但是,这往往不是一个很好的方法,为什么? ① 学生要掌握这个方法的用途,只能通 ...

  9. salesforce 零基础学习(四十五)Approval Lock & UnLock相关注意事项

    我们都知道,当一条记录进入审批流程以后会自动加锁,apex提供Approval类的lock和unlock方法可以让我们使用代码对记录进行加锁和解锁. 项目中遇到一个需求,需要当某种情况下对记录进行先解 ...

  10. SQL分页

    --第一种分页(TOP方式)-- select * from T_Sys_User where User_Id in ( User_Id from T_Sys_User where User_Id n ...