《js高级程序设计》6.1.1-6.1.3——数据属性、访问器属性
数据属性:该属性包含了一个数据值的位置,它包含了4个描述行为的特性:
1. [[Configurable]]:表示是否能通过delete删除属性从而重新定义属性,能否修改属性的特性,能否把属性修改为访问器属性。
2. [[Enumerable]]:表示能否用for-in循环返回。
3. [[writable]]:表示能否修改属性的值。
4. [[Value]]:包含这个属性的数据值。读取属性值的时候从这个位置读,写入属性值的时候更新到这个位置,默认值为undefined。
直接在对象上定义的属性的数据特性默认如下:
1. [[Configurable]]:true
2. [[Enumerable]]:true
3. [[writable]]:true
4. [[Value]]:”xiaochang” (初始时的赋值)
这些特性不能直接被访问,要修改属性的特性只能通过Object.defineProperty( )方法,该方法包含三个参数:属性所在的对象,属性的名字,描述符对象[configurable|enumerable|writable|value]。例如:
var person = {
age:100
}; Object.defineProperty(person,"name",{
configurable:false,
writable:false,
value:"xiaochang"
}); Object.defineProperty(person,"tall",{
value:160
}); for(attr in person){
console.log(attr); //name,age
}
console.log(person.name); //xiaochang
person.name="CC"; //为name属性指定新值
console.log(person.name); //xiaochang
delete person.name; //删除name属性
console.log(person.name); //xiaochang console.log(person.age); //100
person.age=200; //为age属性指定新值
console.log(person.age); //200
delete person.age; //删除age属性
console.log(person.age); //undefined console.log(person.tall); //160
person.tall = 160; //修改tall属性的值
console.log(person.tall); //160
delete person.tall; //删除name属性
console.log(person.tall); //160
分析例子可知直接在对象上定义的属性,如age,[[Configurable]],[[Enumerable]],[[writable]]都被设置为true。
属性name的[[Configurable]],[[writable]]被设置为false,所以无法修改和删除。
调用Object.defineProperty( )方法时,如果不显示指定configurable,enumerable,writable的值,就默认为false,如属性tall。
另外需要注意的是当configurable设置为false后无法再将其改为true,且除了writable之外,无法修改其它特性。在configurable为true的情况下可多次调用Object.defineProperty( )修改同一属性。
在非严格情况下修改无法配置的属性操作会被忽略,在严格模式下会抛出错误。
访问器属性:包含getter和setter函数。读取访问器属性时,调用getter函数,返回有效的值;在写入访问器属性时,调用setter函数传入新值。它包含了4个特性:
1. [[Configurable]]:表示是否能通过delete删除属性从而重新定义属性,能否修改属性的特性,能否把属性修改为访问器属性。
2. [[Enumerable]]:表示能否用for-in循环返回。
3. [[Get]]:读取属性时调用的函数,默认undefined。
4. [[Set]]:写入属性时调用的函数,默认undefined。
getter和setter不一定要成对出现,只有getter函数证明该属性只读不可写,尝试写入在非严格模式下会被忽略,严格模式会抛出错误。相同,只有setter函数证明只写不能读,尝试读在非严格模式下返回undefined,严格模式则抛出错误。
访问器属性无法直接定义,必须使用Object.defineProperty( )来定义,如下:
var person = {
_name:"xiaochang", //name属性只读不可写
_age:100, //age属性只写不可读
_tel:123456 //tel属性可读可写
};
Object.defineProperty(person,"name",{
get:function(){
return this._name;
}
});
Object.defineProperty(person,"age",{
set:function(newage){
this._age = newage;
}
});
Object.defineProperty(person,"tel",{
get:function(){
return this._tel;
},
set:function(newtel){
this._tel= newtel;
}
});
console.log(person.name); //"xiaochang"
person.name = "CC"; //尝试修改name属性
console.log(person.name); //"xiaochang"
console.log(person.age); //不可读属性,undefined
person.age = 200; //修改age
console.log(person._age); //直接读取对象方法才能访问的属性,可以看到值已更新200
console.log(person.tel); //123456
person.age = 654321; //更新tel
console.log(person.tel); //654321
属性前面的下划线表示只能通过对象方法访问的属性,当我们调用person.name时实际调用了name属性的getter函数(直接调用person._name可得到相同的结果,这样做访问器就没什么意义了)。通过上面例子中可以很清晰的看出属性与访问器之间的关系。
支持Object.defineProperty( )方法的浏览器有IE9+(IE8是第一实现Object.defineProperty( )方法的浏览器,但仅限于DOM对象,且只能创建访问器属性)、Firefox4+、Safari5+,Opera12+、Chrome。在不支持Object.defineProperty( )方法的浏览器中不能修改[[Configurable]],[[Enumerable]]。
在Object.defineProperty( )方法之前,要创建访问器属性,一般使用非标准的方法:__defineGetter__()
和__defineSetter__()
,这两个方法最初在Firefox引入,后来chrome1和Opera9.5也支持。改写上面的tel属性访问器如下:
person.__defineGetter__("tel",function(){
return this._tel;
});
person.__defineSetter__("tel",function(newtel){
this._tel = newtel;
ECMAScript 5还定义Object.defineProperties( )方法,该方法包含两个参数:属性所在的对象,多个属性的名字和其描述符对象组成的对象。其作用于Object.defineProperty( )相同,区别是可一次性定于多个属性。支持该方法的浏览器有IE9+、Firefox4+、Safari5+,Opera12+、Chrome。上面的例子可以改写如下:
var person = {
_name:"xiaochang", //name属性只读不可写
_age:100, //age属性只写不可读
_tel:123456 //tel属性可读可写
};
Object.defineProperties(person,{
name:{
get:function(){
return this._name;
}
},
age:{
set:function(newage){
this._age = newage;
}
},
tel:{
get:function(){
return this._tel;
},
set:function(newtel){
this._tel= newtel;
}
}
});
对于上述讲到的属性特性,ECMAScript 5 给出了可以取得给定属性的描述符的方法Object.getOwnPropertyDescriptor(),该方法包含两个参数:属性所在的对象,要读取其描述符的属性名称。方法返回一个对象。如针对上面的例子可得:
var descriptor = Object.getOwnPropertyDescriptor(person,"tel");
for(attr in descriptor ){
console.log(attr+":"+descriptor[attr]);
} 运行结果如下:
get:function (){return this._tel;}
set:function (newtel){this._tel= newtel;}
enumerable:false
configurable:false
原文:http://www.2cto.com/kf/201504/393319.html
《js高级程序设计》6.1.1-6.1.3——数据属性、访问器属性的更多相关文章
- js高级程序设计笔记之-addEventListener()与removeEventListener(),事件解除与绑定
js高级程序设计笔记之-addEventListener()与removeEventListener(),事件解除与绑定 addEventListener()与removeEventListener( ...
- 《JS高级程序设计》笔记 —— 解析查询字符串
今天在继续翻阅<JS高级程序设计>的时候,正好翻到location对象这一小节,其中有一部分就是讲的解析查询字符串.看到这个内容立马想到了做去哪儿秋招笔试题的时候有这么一道题. 去哪儿笔试 ...
- angular.js高级程序设计书本开头配置环境出错,谁能给解答一下
server.jsvar connect=require('connect');serveStatic=require('serve-static');var app=connect();app.us ...
- 读书笔记 - js高级程序设计 - 第十五章 使用Canvas绘图
读书笔记 - js高级程序设计 - 第十三章 事件 canvas 具备绘图能力的2D上下文 及文本API 很多浏览器对WebGL的3D上下文支持还不够好 有时候即使浏览器支持,操作系统如果缺缺 ...
- JS高级程序设计2
面向对象 ,基本模式.对象字面量模式.工厂模式.构造函数模式.原型模式.组合构造函数和原型模式.其他模式见电子书:动态原型模式.寄生构造函数模式(不推荐).稳妥构造函数模式(要求安全的环境,不使用ne ...
- js高级程序设计 笔记 --- 面向对象的程序设计
1,理解对象 通过对象字面量的方式,创建一个对象,为它添加属性和方法: var obj = { a: 1, b:2, sayA(){ console.log(this.a)}} 1,属性类型: 数据属 ...
- Js中的数据属性和访问器属性
Js中的数据属性和访问器属性 在javaScript中,对象的属性分为两种类型:数据属性和访问器属性. 一.数据属性 1.数据属性:它包含的是一个数据值的位置,在这可以对数据值进行读写. 2.数据属性 ...
- js中的访问器属性中的getter和setter函数实现数据双向绑定
嗯,之前在读js红宝书的时候,在对象那一章有介绍属性类型.第一种数据类型指的是数据属性,第二种是访问器属性.在初识vue的时候,其双向数据绑定也是基于访问器属性中的getter和setter函数原理来 ...
- js中属性类型:数据属性与访问器属性
js中属性类型分为两种:数据属性和访问器属性 在js中,对象都是由名值对构成的,名:就是我们所说的属性名,值就是属性对应的值(基本值.对象.方法). ECMA-262第5版定义了只有内部才用的特性,描 ...
随机推荐
- TZ_05_Spring_Transaction的纯注解开发
1.数据库配置 jdbcConfiguation.java 1>使用Spring的EL表达式配合@Value()注解 @Value("${jdbc.Driver}") pri ...
- 关于 matplotlib
注意,需要 zlib, 需要 Tkinter pip install matplotlib import numpy as np import matplotlib.pyplot as plt plt ...
- INotitypropertyChanged
WPF数据绑定(要是后台类对象的属性值发生改变,通知在“client界面与之绑定的控件值”也发生改变须要实现INotitypropertyChanged接口) MainWindow.xaml < ...
- ES6 新的数据类型Map和Set
Map Map是一组键值对的结构,具有极快的查找速度. 举个例子,假设要根据同学的名字查找对应的成绩,如果用Array实现,需要两个Array: var names = ['Michael', 'Bo ...
- Springmvc使用阿里巴巴的fastjson传输到前台中文乱码的解决方案,他娘的大家都少制造垃圾,学习过程将会多么快乐
弄了大概七八个小时吧 都他妈比的抄来抄去,一分一秒的去试错 最终参考这个问题解决了乱码的情况https://bbs.csdn.net/topics/392169549 412 需要在springmvc ...
- canvas旋转图片
canvas旋转图片 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...
- java-异常进阶-包的使用
一 finally 1.1 异常执行的顺序 package test; public class Test { public static void main(String[] args) { Dem ...
- LinqToExcel 简洁与优美开源库
转载:https://www.cnblogs.com/codefish/archive/2013/04/08/3009098.html 正在做项目,同事问道有啥简单的方法读取excel到DataTab ...
- linux交换两个文件的文件名
- Android原生调用mui里面的js如何实现
遍历所有运行中的webview页面,采用自带的SDK方法进行获取所有的IWebview.MUI中自带的webview是一个IWebviewArrayList<IWebview> webli ...