JavaScript 面向对象精要--理解对象

尽管JavaScript里有大量内建引用类型,很可能你还是会频繁的创建自己的
对象。JavaScript中的对象是动态的。

一.定义属性
当一个属性第1次被添加给对象时JavaScript在对上上调用了一个名为
[[Put]]的内部方法,该方法会在对象上创建一个新节点保存属性,就像
哈希表上第一次添加一个键一样这个操作不仅指定了初始值
也定义了属性的一些特征

1.1 [[Put]]内部方法
[[Put]]在对象上创建一个自有属性
1.2 [[Set]]内部方法
当一个属性被赋予一个新值时,调用对象上的[[Set]]内部方法

var person1 = {
name : 'Nicholas'//调用person1上的[[Put]]
}
var person2 = new Object();
person2.name = 'Nicholas'; //调用person2上的[[Put]]
person1.name = 'Greg'; //调用person1上的[[Set]]
perosn2.name = 'Greg' //调用person2上的[[Set]]

二.属性探测
由于属性可以在任何时候添加,所以有时候就有必要
检查对象上是否己有属性
if判断中的值是一个 对象、非空字符串、非0数字和false时
判断为 真;当值为:null、underfined、0、false、NaN或
空字符串时为 假。

2.1 in 探测
in操作符会检查自有属性和原型属性。

var person = {
  name : 'Nicholas'
}
console.log('name' in person) //true;
console.log('age' in person) //false;
console.log('toString' in person) //true;
2.2 hasOwnProperty() 探测
obj.hasOwnProperty('name')只会探测自有属性。
console.log(person.hasOwnProperty('name')) //true;
console.log(person.hasOwnProperty('toString'));//false

三.删除属性
delete操作符删除对象上属性时候,在对象上调用[[Delete]]
内部方法,你可以认为该操作在哈希表中移除一个键值对。
delete操作成功返回true。

var person = {
name : 'Nicholas'
}
console.log('name' in person); //true;
delete person.name //调用[[Delete]] 返回true
console.log('name' in person); //false
console.log(person.name); //undefined

四.属性枚举
4.1 for-in 枚举
所有添加的属性默认都是可枚举的,可以要for-in循环便利
它们,可枚举属性内部特征[[Enumerable]]都被设置为true
for-in会枚举一个对象的所有的可枚举的属性并将属性名赋
给一个变量

var property;
for(perperty in object){
console.log('Name'+property);
console.log('Value'+object[property]);
}

4.2 Object.keys() 方法
Object.keys(obj)可以取得可枚举属性的名字的 数组
只返回 自有 属性,不会遍历原型属性
var properties = Object.keys(obj);
var i,len
for(i = 0,len = properties.length;i<len;i++){
console.log('Name'+ properties[i]);//对象的键名
console.log('Value' = obj[properties[i]]);//对象的值

}
4.3 propertyIsEnumerable() 方法
并不是所有对象都是可枚举的,实际上,对上大部分原生方法的
[[Enumerable]]特征 为 false,你可以使用 propertyIsEnumerable()
方法检查一个属性是否可枚举。每个对象都拥有该方法。

var person = {
name : 'Nicholas'
}
console.log('name' in person) //true
console.log(person.propertyIsEnumerable(name)) //true;
var properties = Object.keys(person);
console.log('length' in properties); //true;
console.log(properties.propertyIsEnumerable('length')) //false;

五.属性类型
属性有两种类型:数据属性 和 访问器属性。
访问器属性不包含值而是定义一个当属性被读取时调用的函数
getter和一个当属性被写入时调用的函数 setter。
5.1 getter和setter

定义一个访问器属性name, _name保存了访问器属性的实际值。
(_约定的命名规范)。

var person = {
_name : 'Nicholas',
get name() {
console.log('name');
return this._name;//返回属性值
},
set name(val){
console.log('set name val');
this._name = val;//设置属性值
}
}
console.log(person.name); //返回'Nicholas'
person.name = 'Greg'; //如果只设置了getter 无法改变name的值
console.log(person.name); //返回'Greg'

你并不一定同时定义setter和getter,如果只定义了getter
该属性就变成了 只读

六.属性特征
ECMAScript5引入了多种方法来和属性特征之间互动

6.1 通用特征 [[Enumerable]] [[Configurable]]
[[Enumerable]] 决定了是否可以遍历该属性;
[[Configurable]] 决定了该属性是否可配置;
Object.defineProperty() 方法 可以用来改变属性的特征。
接受 3 个参数 :该属性的对象、该属性名、设置特征的对象。

var person = {
name : 'Nicholas'
}
Object.defineProperty(person,'name',{
enumerable : false,
configurable : false
})
console.log('name' in person) //true;
console.log(person.propertyIsEnumerable('name')) //false;
var propers = Object.keys(person);
console.log(propers.length) // delete person.name; //无法删除
console.log(person.name) //'Nicholas'
Object.defineProperty(person,'name',{
configurable : true //报错
})

6.2 数据属性特征
数据属性包含 访问器属性不具有的两个特征。
[[Value]]和 [[Writable]]
[[Value]] 保存属性的值;
[[Writable]] 属性是否可以写入

var person = {
name : 'Nicholas'
}
Object.defineProperty(person,'name',{
value : 'Greg',
enumerable : true,
configurable : true,
writable : true
})

当Object.defineProperty()被调用时,首先检查属性是否存在。
如果不存在,根据对象指定的特征创建值。
当你使用Object.defineProperty()创建属性时,一定要记得为
所有特征制定一个值,否则 布尔型 的特征会被默认设置为 false

6.3 访问器属性
访问器属性也有两个额外的特征,访问器属性不需要存储值
因此就没有[[Value]]和[[Writable]]。取而代之的是[[Get]]
和 [[Set]]和对象直面形式的 getter和setter一样。

var person = {
_name : 'Nicholas',
get name(){
return this._name;
},
set name(val){
this._name = val;
}
}
//这段代码可以改写成:
var person = {
_name : 'Nicholas'
}
Object.defineProperty(person,'name',{
get : function(){
return this._name;
},
set : functiono(val){
this._name = val;
},
  enumerable : true,
  configurable : true
})

6.4 定义多重属性
使用Object.defineProperties(obj,{})来为一个对象
定义多个属性的特征

var person = {};
Object.defineProperties(person,{
_name : {
value : 'Nicholas',
enumerable : true,
configurable : true,
writable : true
},
name : {
get : function(){
return this.name;
},
set : function(val){
this.name = val;
},
enumerable : true,
configurable : true }
})

定义了_name数据属性和name访问器属性。

6.5 获取属性的特征
使用Object.getOwnPropertyDescriptor()方法返回属性的特征
的一个对象即使没有被显示的定义。
接受两个参数 属性所在的对象、属性名。

var person = {
  name = 'Nicholas'
}
var descriptor = Object.getOwnPropertyDescriptor(person,'name');
console.log(descriptor.enumerable); //true
console.log(descriptor.configurable); //true
console.log(descriptor.writable); //true
console.log(descriptor.value); //'Nicholas'

七.禁止修改对象
[[Extensible]]是一个布尔值,它指明该对象特征是否可被修改。
你创建的所有对象默认都是可被扩展的,意味着新的属性可以随时
添加

7.1 禁止扩展
Object.preventExtensions()方法创建一个不可扩展的对象。
Object.isExtensible()来检查[[Extensible]]的值。

var person = {
name : 'Nicholas'
}
console.log(Object.isExtensible(person)); //ture
Object.preventExtensions(person);
console.log(Object.isExtensible(person)); //flase
person.sayName = function(){
console.log(this.name);
};
console.log('sayName' in person); //false

7.2 对象封印
对象封印是创建一个不可扩展的对象的第二个方法。
一个封印的对象是不可扩展且所有属性都不可配置
如果一个对象被封印,只能读写他的属性
使用Object.seal() 方法封印对象
被调用时 [[Extensible]]和[[Configurable]]特征为 false.
可以用Object.isSealed()判断对象是否被封印。

var person = {
name : 'Nicholas'
}
console.log(Object.isExtensible(person)) // 是否扩展 true
console.log(Object.isSealed(person)) //是否被封印 false
Object.seal(person) //封印对象
console.log(Object.isExtensible(person)) // 是否扩展 false
console.log(Object.isSealed(person)) //是否被封印 true

7.3 对象冻结
创建不可扩展的第三个方法就是冻结它。
如果一个对象被冻结,则不能在其上添加和删除属性
不能改变属性类型,也不能写入任何数据属性。
Object.freeze()来冻结一个对象
Object.isFrozen()判断一个对象是否被冻结。

var person = {
name : "Nicholas"
}
console.log(Object.isExtensiable(person)) //是否扩展 true
console.log(Object.isSealed(person)) //是否封印 false
console.log(Object.isFrozen(person)) //是否冻结 false
Object.freeze(person) //冻结对象
console.log(Object.isExtensiable(person)) //是否扩展 false
console.log(Object.isSealed(person)) //是否封印 true
console.log(Object.isFrozen(person)) //是否冻结 true

03.JavaScript 面向对象精要--理解对象的更多相关文章

  1. javascript 面向对象程序设计--深刻理解对象

    javascript中,每个对象都是基于一个引用类型创建的,我们可以把ECMAScript 的对象想象成散列表:无非就是一组名值对,其中值可以是数据或函数. 深刻理解对象 创建自定义对象的最简单方式就 ...

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

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

  3. javascript面向对象精要第三章对象整理精要

    什么是对象的数据属性?什么是对象的访问器属性?[put]方法是默认创建数据属性的,访 问器属性不包含值而是定义了一个单属性被读取时调用的函数(getter)和当一个属性被写入时 调用的函数(sette ...

  4. 《javascript面向对象精要》读书笔记

    <javascript面向对象精要> 买这本书的原因主要是因为作者,Nicholas C. Zakas 牛X闪闪的js专家,读过js高程的应该都知道他,而这本书是他的最新力作,感觉也是js ...

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

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

  6. JavaScript面向对象精要(一)

    数据类型 在JavaScript中,数据类型分为两类: 原始类型:保存一些简单数据,如true.5等.JavaScript共同拥有5中原始类型: boolean:布尔.值为true或false num ...

  7. JavaScript面向对象精要

    来自:淡忘~浅思. 链接:http://www.ido321.com/1585.html 和 http://www.ido321.com/1586.html 数据类型   在JavaScript中,数 ...

  8. javascript面向对象精要第六章对象模式整理精要

    混入是一种给对象添加功能同时避免继承的强有力的方式,混入时将一个属性从一个对象 复制到另一个,从而使得接收者在不需要继承的情况下获得其功能.和继承不同,混入之后 对象无法检查属性来源.因此混入最适宜用 ...

  9. javascript面向对象精要第四章构造函数和原型对象整理精要

随机推荐

  1. robotium重签名使用解决办法

    用re-sign重新签名,出现error,提示缺少zipalign 解决方案: 下载zipalign.exe,地址:http://pan.baidu.com/s/1geoHemR 下载后将zipali ...

  2. Repeater的Item项绑定DropDownList

    前台页面: <asp:Repeater ID="rptJgtList" runat="server" OnItemDataBound="rptJ ...

  3. ASP.NET MVC 异步获取和刷新ExtJS6 TreeStore

    从数据库获取构造树结构是ExtJS TreePanel的核心技术,常用方法是TreeStroe里配置proxy,这种方式的root成了一个不受控制的节点. TreeStroe的root实际是一个层叠j ...

  4. 初学Objective-C语言需要了解的星星点点

             其实大多数开发初学者都有一些相同的特点,可以说是一种“职业病”.Most有其他平台开发基础的初学者,看到Xcode就想摩拳擦掌:看到Interface Builder就想跃跃欲试:而 ...

  5. 精益化设计:把敏捷方法和Lean UX相结合

    敏捷方法已经成为了主流.同时,Kindle和iPhone等设备取得的巨大成功也推动了体验设计的飞速发展.不过,如何把敏捷方法和UX设计结合起来,一直以来都是一个难题.文章将探讨如何把UX融入到最流行的 ...

  6. FastJson转换自定义枚举类

    在项目中有些状态需要采用枚举类型,在数据库中保存的是name(英文),而前台需要显示的是text(中文). 所以这就需要自己去实现序列. 例如对象: import java.util.Date; im ...

  7. Dynamics AX 2012 R2 业务系列-销售业务流程

    在博文Dynamics AX R2 业务系列中,Reinhard对这个系列做了一个规划,下面我们就按照规划开始说业务吧. 1.销售的主要职责 其实这里说的职责主要是针对销售文员,并非整天外面满世界跑业 ...

  8. EBS learning history (to know about the environment)

    prcsgidb1: /u01/Stage/database C:\Users\alley_li>ping prcsgidb1 Pinging prcsgidb1.ad.infosys.com ...

  9. kafka0.9.0及0.10.0配置属性

    问题导读1.borker包含哪些属性?2.Producer包含哪些属性?3.Consumer如何配置?borker(0.9.0及0.10.0)配置Kafka日志本身是由多个日志段组成(log segm ...

  10. [课程设计]Scrum 3.5 多鱼点餐系统开发进度(修复Bug&美化页面)

    Scrum 3.5 多鱼点餐系统开发进度(修复Bug&美化页面) 1.团队名称:重案组 2.团队目标:长期经营,积累客户充分准备,伺机而行 3.团队口号:矢志不渝,追求完美 4.团队选题:餐厅 ...