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()方法。

JS高程3:面向对象的程序设计——理解对象的更多相关文章

  1. [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示

    javascript面向对象编程方式,对于初学者来说,会比较难懂. 要学会面向对象以及使用面向对象编程,理解对象的创建在内存中的表示,至关重要. 首先,我们来一段简单的对象创建代码 var obj = ...

  2. 03.JavaScript 面向对象精要--理解对象

    JavaScript 面向对象精要--理解对象 尽管JavaScript里有大量内建引用类型,很可能你还是会频繁的创建自己的对象.JavaScript中的对象是动态的. 一.定义属性 当一个属性第1次 ...

  3. 【学习笔记】六:面向对象的程序设计——理解JS中的对象属性、创建对象、JS中的继承

    ES中没有类的概念,这也使其对象和其他语言中的对象有所不同,ES中定义对象为:“无序属性的集合,其属性包含基本值.对象或者函数”.现在常用的创建单个对象的方法为对象字面量形式.在常见多个对象时,使用工 ...

  4. JS_高程6.面向对象的程序设计(1)理解对象

    js的数据属性:P139(1)[[Configurable]](2)[[Enumerable]](3)[[Writable]](4)[[Value]] 使用Object.definerPropert( ...

  5. 面向对象 ( OO ) 的程序设计——理解对象

    本文地址:http://www.cnblogs.com/veinyin/p/7607938.html  1 创建自定义对象 创建自定义对象的最简单方法为创建 Object 的实例,并添加属性方法,也可 ...

  6. 重学js之JavaScript 面向对象的程序设计(创建对象)

    注意: 本文章为 <重学js之JavaScript高级程序设计>系列第五章[JavaScript引用类型]. 关于<重学js之JavaScript高级程序设计>是重新回顾js基 ...

  7. JS_高程6.面向对象的程序设计(2)创建对象_1

    一.创建对象的常见方法 (1)Object构造函数创建单个对象,早期的JavaScript开发人员经常使用该模式创建新对象. var person=new Object(); person.name= ...

  8. 转载:Javascript面向对象编程原理 -- 理解对象

    源地址:http://www.html-js.com/article/1717 虽然JavaScript中已经自带了很多内建引用类型,你还是会很频繁的需要创建自己的对象.JavaScript编程的很大 ...

  9. JS_高程6.面向对象的程序设计(2)创建对象_3 构造函数存在的问题

    # 上次讲到用构造函数的模式来创建对象,相对于工厂模式,解决可对象识别的问题. function Person(name,age,job){ this.name=name; this.age=age; ...

随机推荐

  1. [转]SSIS中的脚本—脚本任务

    本文转自:http://www.cnblogs.com/tylerdonet/archive/2011/09/16/2179123.html 脚本任务主要用来控制数据流,当现有的控制流 任务不能满足复 ...

  2. 配置thinkphp3.2 404页面

    ThinkPHP自身提供了 404 页面的处理机制,我们只需要在控制器 中添加一个 EmptyController.class.php,并且实现以下方法即可,方法如下: <? class  Em ...

  3. Spark Streaming数据清理内幕彻底解密

    本讲从二个方面阐述: 数据清理原因和现象 数据清理代码解析 Spark Core从技术研究的角度讲 对Spark Streaming研究的彻底,没有你搞不定的Spark应用程序. Spark Stre ...

  4. 关于Web界面查看日志的权限问题

    关于Web界面查看日志的权限问题 @(Hadoop) 访问集群的8088端口,通过web ui查看作业日志时,发现没有权限查看,8088主界面右上角显示Logged in as : dr.who,即匿 ...

  5. 使用RMAN和控制文件备份删除归档日志的SHELL脚本--RED HAT 5 LINUX 64

    在ORACLE用户下的定时器设置 [oracle@SHARKDB dbscripts]$ crontab -l# minute hour day month week15 1  * * 0  sh / ...

  6. [HTML5] Add an SVG Image to a Webpage and Get a Reference to the Internal Elements in JavaScript

    We want to show an SVG avatar of the patio11bot, so we'll do that in three ways: Using an img tag - ...

  7. 【Spark】RDD操作具体解释2——值型Transformation算子

    处理数据类型为Value型的Transformation算子能够依据RDD变换算子的输入分区与输出分区关系分为下面几种类型: 1)输入分区与输出分区一对一型 2)输入分区与输出分区多对一型 3)输入分 ...

  8. Android的四大天王

    Android 四大天王 1.Activity  2.Intent Receiver 3.Service 4.Content Provider   但是,并不是每一个Android应用程序都需要这四种 ...

  9. PHP基础知识(二)

    Global namespace  //看不懂看下面的中文 中英结合看看 When using namespaces, you may find that internal functions(内部( ...

  10. PHP变量引用赋值与变量赋值变量的区别

    变量默认总是传值赋值.那也就是说,当将一个表达式的值赋予一个变量时,整个原始表达式的值被赋值到目标变量.这意味着,例如,当一个变量的值赋予另外一个变量时,改变其中一个变量的值,将不会影响到另外一个变量 ...