对象

对象是JavaScript基本数据类型。可以看做是属性的一种无序集合。

 

1.创建对象

对象直接量

创建对象的最简单的方式就是在JavaScript代码中使用对象直接量。

一些例子:

var empty={};
var point={x:0,y:0};
var point2={x:point.x,y:point.y+1};
var book={
    "mian-title":"JavaScript",
    "sub-title":"The Definitive Guide",
    "for":"all audiences",
    author: {
      firstname:"David",
      lastname:"Flanagan"
    }
}

通过new创建对象

new运算符创建并初始化一个新对象。

var o=new Object();
var a=new Array();
var d=new Date();
var r=new RegExp("js");

原型

每一个JavaScript对象(除null外)都与另一个对象相关联,“另一个”对象就是我们熟知的原型,每一个对象都重原型继承属性。

通过对象直接量创建的对象都具有同一个原型对象,通过Object.prototype获取对原型对象的引用。通过new Object()创建的对象继承自Object.prototype;通过new Array()创建的对象的原型就是Array.prototype.

没有原型的对象不多,Object.prototype就是其中之一。

Object.create()创建对象

Object.create()是一个静态函数,它创建一个新对象,第一个参数是这个对象的原型,第二个参数时可选的,用于对该对象的描述

var o1=Object。create({x:1,y:2}); //o1继承了属性x和y
如果参数为null,不继承任何东西,把偶奇偶toString()等
创建一个普通的空对象,可以这样:
var o2=Object.create(Object.prototype);

 

2.属性的查询和设置

可以通过.或者方括号[]运算来得到属性的值

继承

JavaScript对象具有"自有属性“,也有一些属性是从原型对象继承而来的。

如果要查询对象o的属性x,如果o中不存在,则往他的原型中查找,知道找到x或者找到一个原型是null的队形为止。

JavaScript继承使用inherit()函数

var o={};
o.x=1;
var p=inherit(o);  //对象p继承对象o
p.y=2;
var q=inherit(p);
q.z=3;
var s=q.toString();
q.x+q.y

访问属性错误

查询一个不存在的属性不会报错,没有找到返回undefined

但是,查询不存在的对象的属性会报错。

var len=book.subtitle.length; //不存在book,undefined没有length属性
除非确定对应对象存在否则不能上面这样写
优化:
var lerr=undefined;
if(book){
  if(book.subtitle){
    len=book.subtitle.length;
  }
}

var len=book&&book.subtitle&& book.subtitle.length;

删除属性

delete运算符的使用

this.x=1;

delete x;

检测属性

通过in运算符、hasOwnPreperty()、和propertyIsEnumerable()完成

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

var o={x:1};
"x" in o; ==>true
"y" in o; ==>false
"toString" in o==>true

hasOwnProperty()检测给定的名字是否是对象的自由属性。对于继承属性它返回false

var o={x:1};
o.hasOwnProperty("x"); ==>true
o.hasOwnProperty("y"); ==>false
o.hasOwnProperty("toString"); ==>false

peopertyIsEnumerable()是hasOwnProperty()的增强版,只有检测到自由属性,且这个属性的可枚举型为true才返回true

枚举属性

遍历对象的属性,通常使用for/in循环

for/in循环可以遍历对象中所有可枚举属性

Object.keys()返回一个由对象中可枚举的自有属性名称组成的数组

Object.getOwnPropertyNames()返回对象的所有自有属性的名称属性的geteter、setter

对象属性是由名字、值和一组特征构成的。在ECMAScript5中,属性值可以用一个或两个方法替代。这两个方法就是getter和setter。由getter和setter定义的属性称为”存取器属性“。

当程序查询存取属性的值的时候,JavaScript调用getter方法(无参数)。这个方法的返回值就是属性存取表达式的值。JavaScript调用setter方法,将赋值表达式右侧的值当作参数传入setter。

存取器属性具有不可写性。如果属性同时具有getter和setter方法,那么它是一个读写属性。如果只有getter方法,只读属性。如果只有setter方法,是一个只写属性,读取只写属性会反悔undefined。

var o={
   data_prop:value,
  get accessor_prop(){....},
  set accessor_prop(value){...}
};
console.log(o.accessor_prop); 存取器属性定义为一个或两个和属性同名的函数,这个函数定义没有使用function关键字,而是使用get和(或)set方法。

对象的继承会继承到存取器属性

 

7.对象的三个属性

原型属性

前面介绍了新建对象一般是使用的对象的原型属性

检测一个对象是否是另一个对象的原型(或处于原型链中),使用isPeototypeOf()方法

var p={x:1};
var o=Object.create(p);
p.isPrototypeOf(o);  ==>true
Object.prototype.isPrototypeOf(o);==>true

类属性

对象的类属性是一个字符串,用以表示对象的类型信息。

查询对象的类属性要使用默认的toString()方法

function classof(o){
  if(o==null) return "Null";
  if(o==undefined) return "Undefined";
  return Object.property.toString.call(o).slice(8,-1);
 //这里为了调用正确的toString()版本,必须简介地调用Function.call()方法。
}

实际上是这些类型的变量调用toString()方法,而不是通过它们的直接量调用toString()。比如1.toSring()是不对的,而是要先声明变量 var a=1;然后调用a.toString()。

可拓展性

对象的可拓展性用以表示是否可以给对象添加新属性。所有内置对象和自定义对象都是可拓展的,宿主对象的可拓展性是由JavaScript引擎定义的。

Object.esExtensible(obj)判断该对象obj是否是可拓展的。

Object.preventExtensions(obj)将对象转换成不可拓展的

Object.seal(obj)除了能将对象设置为不可拓展的,还可以将对象的所有自有属性都设置为不可配置的。对于那些已经封闭(sealed)起来的对象是不能解封的。可以使用Object.isSealed()来检测对象是否封闭

Object.freeze()将冻结对象。除了将对象设置称为不可拓展的和将其属性配置为不可配置的外,还将所有的数据属性设置为只读的(如果对象存取器属性具有setter方法,存取器属性不受影响)。Object.isFrozen()来检测对象是否被冻结

 

8.序列化对象

对象序列化(serialization)是指将对象的状态转换为字符串,也可将字符串还原为对象。

ECMAScript5提供了内置函数JSON.stringify()和JSON.parse()来序列化和还原JavaScript对象。这些方法都是用JSON作为数据交换格式,JSON的全称是JavaScript Object Notation(JavaScript对象表示法,它的语法和JavaScript对象与数组直接量的语法非常相似)

o={x:1,y:{z:[false,null,""]}};
s=JSON.stringify(o);    //s是'{"x":1,"y":{"z":[false,null,""]}}}'
p=JSON.parse(s);    //p是c的深拷贝

 

9.对象方法

toString()方法:返回一个表示调用这个方法的对象值的字符串。

var s={x:1,y:1}.toString();  ==>[object Object]

toLocaleString()方法

返回这个对象的本地化字符串。Object中默认的toLocalString()方法并不做任何本地化自身的操作,它仅调用toString()方法并返回对应值。

Date和Number类对toLocaleString()做了定责,可以用它对数字、日期和时间做本地化的转换。Array类中的这个方法和toString()方法很像,唯一不同的是每个数组元素会调用toLocaleString()方法转换为字符串,而不是调用各自的toString()方法

toJSON()方法

返回的是序列化的结果Object。property实际上没有定义,单数对于需要执行序列化的对象来说,JSON.stringify()方法会调用同JSON方法。如果在待序列化的对象中存在这个方法,则调用它,返回值即是序列化的结果。

valueOf()方法

valueOf()方法和toString()非常相似。但往往JavaScript需要将对象转换为某种原始值而非字符串的时候才会调用它,尤其是转换为数字的时候。

Integer.valueOf("1");

 

posted @ 2016-05-02 20:11  guodaxia  阅读(187)  评论(0编辑  收藏  举报