首页 > 代码库 > JavaScript面向对象学习——4

JavaScript面向对象学习——4

对象的创建

1)字面量、2)new、3)Object.create()

属性的访问

1、可以通过点(.)或方括号([」)运算符来获取属性的值。运算符左侧应当是一个表达式,它返回一个对象。对于点(.)来说,右侧必须是一个以属性名称命名的简单标识符。对于方括号来说(「)),方括号内必须是一个计算结果为字符串的表达式,这个字符串就是属性的名字。在ECMAScript 3中,点运算符后的标识符不能是保留字,比如,o.for或o.class是非法的,因为for是JavaScript的关键字,class是保留字。如果一个对象的属性名是保留字,则必须使用方括号的形式访问它们,比如。[ "for" ]和。[ "class"] o ECMAScript 5对此放宽了限制(包括ECMAScript 3的某些实现),可以在点运算符后直接使用保留字。当使用方括号时,我们说方括号内的表达式必须返回字符串。其实更严格地讲,表达式必须返回字符串或返回一个可以转换为字符串的值。在第7章里有一些例子中的方括号内使用了数字,这情况象是非常常见的。

2、假设要查询对象。的属性X,如果。中不存在X,那么将会继续在。的原型对象中查询属性x。如果原型对象中也没有X,但这个原型对象也有原型,那么继续在这个原型对象的原型上执行查询,直到找到X或者查找到一个原型是f1U11的对象为止。可以看到,对象的原型属性构成了一个“链”,通过这个“链”可以实现属性的继承。

删除属性

delete运算符可以删除对象的属性。它的操作数应当是一个属性访问表达式。让人感到意外的是,delete只是断开属性和宿主对象的联系,而不会去操作属性中的属性。delete运算符只能删除自有属性,不能删除继承属性(要删除继承属性必须从定义这个属性的原型对象上删除它,而且这会影响到所有继承自这个原型的对象)。

检测属性

1、JavaScript对象可以看做属性的集合,我们经常会检测集合中成员的所属关系—判断某个属性是否存在于某个对象中。可以通过in运算符、hasOwnPreperty()和propertyIsEnumerable()方法来完成这个工作,甚至仅通过属性查询也可以做到这一点。

2、in运算符的左侧是属性名(字符串),右侧是对象。如果对象的自有属性或继承属性中包含这个属性则返回true:

3、对象的hasOwnProperty()方法用来检测给定的名字是否是对象的自有属性。对于继承属性它将返回false:

4、propertyIsEnumerable()是hasOwnProperty()的增强版,只有检测到是自有属性且这个属性的可枚举性(enumerable attribute)为true时它才返回true。某些内置属性是不可枚举的。通常由JavaScript代码创建的属性都是可枚举的

5、然而有一种场景只能使用in运算符而不能使用上述属性访问的方式。in可以区分不存在的属性和存在但值为undefined的属性

对象的三个属性

1、要想检测一个对象是否是另一个对象的原型(或处于原型链中),请使用isPrototype0f()方法。例如,可以通过p.isPrototype0f(o)来检测P是否是o的原型.

2、对象的类属性(class attribute)是一个字符串,用以表示对象的类型信息。ECMAScript3和ECMAScript 5都未提供设置这个属性的方法,并只有一种间接的方法可以查询它。默认的toString()方法(继承自Object.prototype)返回了如下这种格式的字符串.

Object.prototype.toString.call(o).slice(8,-1);

对象的可扩展性用以表示是否可以给对象添加新属性。所有内置对象和自定义对象都是显式可扩展的,宿主对象的可扩展性是由JavaScript引擎定义的。在ECMAScript 5中,所有的内置对象和自定义对象都是可扩展的,除非将它们转换为不可扩展的,同样,宿主对象的可扩展性也是由实现ECMAScript 5的JavaScript引擎定义的。

对象序列化

1、对象序列化(serialization)是指将对象的状态转换为字符串,也可将字符串还原为对象。ECMAScript 5提供T内置函数JSON.stringify()和JSON.parse()用来序列化和还原JavaScript对象。这些方法都使用JSON作为数据交换格式,JSON的全称是“JavaScriptObject Notation"—   JavaScript对象表示法,它的语法和JavaScript对象与数组直接量的语法非常相近:

2、JSON的语法是JavaScript语法的子集,它并不能表示JavaScript里的所有值。支持对象、数组、字符串、无穷大数字、true, false和null,并且它们可以序列化和还原。NaN,Infinity和一Infinity序列化的结果是null,日期对象序列化的结果是JSON格式的日期字符串(参照Date.toJSON()函数),但JSON.parse()依然保留它们的字符串形态,而不会将它们还原为原始日期对象。函数、RegExp, Error对象和undefined值不能序列化和还原。JSDN.stringify()只能序列化对象可枚举的自有属性。对于一个不能序列化的属性来说,在序列化后的输出字符串中会将这个属性省略掉。JS0N.stringify()和JSON.parse()都可以接收第二个可选参数,通过传入需要序列化或还原的属性列表来定制自定义的序列化或还原操作。

对象的方法

1、hasOwnProperty(). propertyIsEnumerable()和isPrototype0f()这三个方法,以及在Object构造函数里定义的静态函数Object.

create()和Object.getPrototype0f()等方法需要一定了解。

2、toString()方法没有参数,它将返回一个表示调用这个方法的对象值的字符串。在需要将对象转换为字符串的时候,JavaScript都会调用这个方法。比如,当使用“+"运算符连接一个字符串和一个对象时或者在希望使用字符串的方法中使用了对象时都会调用toString()

3、除了基本的toString()方法之外,对象都包含toLocaleString()方法,这个方法返回一个表示这个对象的本地化字符串。Object中默认的toLocaleString()方法并不做任何本地化自身的操作,它仅调用toString()方法并返回对应值。Date和Number类对toLocaleString()方法做了定制,可以用它对数字、日期和时间做本地化的转换。Array类的toLocaleString()方法和to5tring()方法很像,唯一的不同是每个数组元素会调用toLocaleString()方法转换为字符串,而不是调用各自的toString()方法。

4、Object.prototype实际上没有定义toJSON()方法,但对于需要执行序列化的对象来说,JsON.stringify()方法会调用toJSON()方法。如果在待序列化的对象中存在这个方法,则调用它,返回值即是序列化的结果,而不是原始的对象。具体示例参见Date.toJSON()。

5、value0f()方法和toString()方法非常类似,但往往当JavaScript需要将对象转换为某种原始值而非字符串的时候才会调用它,尤其是转换为数字的时候。如果在需要使用原始值的上下文中使用了对象,JavaScript就会自动调用这个方法。默认的value0f()方法不足为奇,但有些内置类自定义}value0f()方法(比如Date.value0f()),9.6.3节讨论如何给自定义对象类型定义value0代)方法。


JavaScript面向对象学习——4