JS中对象的定义:

  • (无序)属性的集合
  • (无序)值的集合
  • (无序)名值对的集合

JS对象是基于引用数据类型来创建的。

JS对象创建的2种方式:

  • 传统方式
  • 对象字面量
var person = new Object();
person.name = "Nicholas";
person.age = 29;
person.job = "Software Engineer";
person.sayName = function(){
alert(this.name);
};

对象字面量

var person = {
name: "Nicholas",
age: 29,
job: "Software Engineer",
sayName: function(){
alert(this.name);
}
};

属性

JS定义了属性的特性来描述属性。特性由内部值和包含内部值的一对方括号组成:

[[Enumerable]]

Enumerable为内部值。

JS属性分为2种:

  • 数据属性
  • 访问器属性

1.数据属性

数据属性包含一个数据值位置。(数据值即上面提到的名值对中的值)

数据属性有4个特性:

 [[Configurable]]:表示能否通过 delete 删除属性从而重新定义属性,能否修改属性的特
性,或者能否把属性修改为访问器属性。像前面例子中那样直接在对象上定义的属性,它们的
这个特性默认值为 true。
 [[Enumerable]]:表示能否通过 for-in 循环返回属性。像前面例子中那样直接在对象上定
义的属性,它们的这个特性默认值为 true。
 [[Writable]]:表示能否修改属性的值。像前面例子中那样直接在对象上定义的属性,它们的
这个特性默认值为 true。
 [[Value]]:包含这个属性的数据值。读取属性值的时候,从这个位置读;写入属性值的时候,
把新值保存在这个位置。这个特性的默认值为 undefined。

下面来看看几个使用这些特性的实例:

要修改属性默认的特性,必须使用 ECMAScript 5 的 Object.defineProperty()方法。这个方法
接收三个参数:属性所在的对象、属性的名字和一个描述符对象。其中,描述符(descriptor)对象的属
性必须是: configurable、 enumerable、 writable 和 value。
var person = {};
Object.defineProperty(person, "name", {
writable: false,
value: "Nicholas"
});
alert(person.name); //"Nicholas"
person.name = "Greg";
alert(person.name); //"Nicholas"

上面writable特性被设置为了false,即数据值不能够被修改。

var person = {};
Object.defineProperty(person, "name", {
configurable: false,
value: "Nicholas"
});
alert(person.name); //"Nicholas"
delete person.name;
alert(person.name); //"Nicholas"

上面configurable特性被设置为false,即不能够删除属性。

注意:尽量不要设置这些特性,尤其是configurable特性,因为一旦configurable为false,就无法再设置这些特性了。

2.访问器属性

访问器属性有4个特性:

 [[Configurable]]:表示能否通过 delete 删除属性从而重新定义属性,能否修改属性的特
性,或者能否把属性修改为数据属性。对于直接在对象上定义的属性,这个特性的默认值为
true。
 [[Enumerable]]:表示能否通过 for-in 循环返回属性。对于直接在对象上定义的属性,这
个特性的默认值为 true。
 [[Get]]:在读取属性时调用的函数。默认值为 undefined。
 [[Set]]:在写入属性时调用的函数。默认值为 undefined。

访问器属性不包含数据值,只能通过Object.defineProperty() 来定义:

var book = {
_year: 2004,
edition: 1
};
Object.defineProperty(book, "year", {
get: function(){
return this._year;
},
set: function(newValue){
if (newValue > 2004) {
this._year = newValue;
this.edition += newValue - 2004;
}
}
});
book.year = 2005;
alert(book.edition); //2

上面,_year表示数据属性,在前面加上下划线,表示只能通过方法来访问该属性。

year表示访问器属性,访问器属性包含getter和setter函数。getter 函数返回_year 的值, setter 函数通过计算来确定正确的版本。
将year属性设置为了2005,会去调用setter函数接收2005并将_year设置为2005,然后edition值也会修改为新值。

注意:只指定getter函数,意味着属性只读;只指定setter函数,意味着属性不能读。

早期时候的实现方法:

var book = {
_year: 2004,
edition: 1
};
//定义访问器的旧有方法
book.__defineGetter__("year", function(){
return this._year;
});
book.__defineSetter__("year", function(newValue){
if (newValue > 2004) {
this._year = newValue;
this.edition += newValue - 2004;
}
});
book.year = 2005;
alert(book.edition); //2

注意:在 不 支 持 Object.defineProperty() 方 法 的 浏 览 器 中 不 能 修 改 [[Configurable]] 和[[Enumerable]]。

定义多个属性

由于经常需要为对象定义多个属性,所以ECMAScript 5定义了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;
}
}
}
});

以上代码在 book 对象上定义了两个数据属性(_year 和 edition)和一个访问器属性(year) 。

读取属性的特性

使用 ECMAScript 5 的 Object.getOwnPropertyDescriptor()方法,可以获取给定属性的描述
符对象。这个方法接收两个参数:属性所在的对象和要读取其描述符对象的属性名称。

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;
}
}
}
});
var descriptor = Object.getOwnPropertyDescriptor(book, "_year");
alert(descriptor.value); //2004
alert(descriptor.configurable); //false
alert(typeof descriptor.get); //"undefined"
var descriptor = Object.getOwnPropertyDescriptor(book, "year");
alert(descriptor.value); //undefined
alert(descriptor.enumerable); //false
alert(typeof descriptor.get); //"function"

注意:在 JavaScript 中,可以针对任何对象——包括 DOM 和 BOM 对象,使用 Object.getOwnPropertyDescriptor()方法。

最新文章

  1. 常用的SQL语句
  2. JsonFormatter PrettyPrint
  3. LR检查点的if (status == LR_FAIL)写法
  4. STM32学习笔记(五) USART异步串行口输入输出(轮询模式)
  5. codeforces A. Bayan Bus(简单模拟)
  6. 怎样写 OpenStack Neutron 的 Extension (一)
  7. 关于eclipse中maven项目的问题
  8. js调试-定位到函数所在文件位置
  9. Day 16: Goose Extractor —— 好用的文章提取工具
  10. 剑指offer 连续子序列和
  11. virtualbox+ievms:还你一个原装IE8
  12. Nodejs全局安装和本地安装的区别
  13. 3070 Fibonacci
  14. java多线程系列11 juc包下的队列
  15. 【Java基础】11、java方法中只有值传递,没有引用传递
  16. 【转】CentOS 7.X 系统安装及优化
  17. canvas 实现弹跳效果
  18. 树莓派进阶之路 (018) - raspberryPi摄像头命令行软件raspistill帮助文档
  19. 前端js如何生成一个对象,并转化为json字符串
  20. 公司里面用的iTextSharp(教程)---生成一个简答的PDF的语法

热门文章

  1. Linux makefile 教程
  2. juqery.fn.extend和jquery.extend
  3. dl,dt,dd标记在网页中要充分利用
  4. iOS:tableView表头下拉放大的效果
  5. window环境下备份与恢复(实际操作)
  6. 跟着我从零开始入门FPGA(一周入门XXOO系列)-1、Verilog语法
  7. DevExpress 中 汉化包 汉化方法
  8. Struts2中的页面跳转
  9. MongoDB之Map-Reduce -- Mongo Shell版和C#版(上)
  10. vue 不能监测数组长度变化length的原因