一篇文章带你了解JavaScript-对象
创建对象
对象直接量
对象直接量是由若干名/值对组成的映射表,名/值对中间用冒号分隔,名/值对之间用逗号分隔,整个映射表用花括号括起来。
var empty = {}; var point = { x:0, y:0}; var point2 = {x:point.x, y:point.y+1}; var book = { "main title":"javascript", //属性名字里有空格,必须用字符串表示 "sub-title":"the", //属性名字里有连字符,必须用字符串表示 "for":"all", //"for"是保留字,必须用字符串表示 author:{ //这个属性的值是一个对象 name:"123" //注意,在里的属性名都没有引号 } };
通过new创建对象
var o = new object(); //创建一个空对象,和{}一样 var a = new array(); //创建一个空数组,和[]一样 var d = new date(); //创建一个表示当前时间的date对象 var r = new regexp("js"); //创建一个可以进行匹配的regexp对象
原型
所有通过对象直接量创建的对象都具有同一个原型对象,并可以通过javascript代码object.prototype获得对原型对象的引用。通过关键字new和构造函数调用创建的对象的原型就是构造函数的prototype属性的值。因此,同使用{}创建对象一样,通过new object()创建的对象也继承自object.prototype。同样,通过new array()创建的对象的原型就是array.prototype,通过new date()创建的对象的原型就是date.prototype。
没有原型的对象为数不多,object.prototype就是其中之一。它不继承任何属性。其他原型对象都是普通对象,普通对象都具有原型。所有的内置构造函数(以及大部分自定义的构造函数)都具有一个继承自object.prototype的原型。例如,date.prototype的属性继承自object.prototype,因此由new date()创建的date对象的属性同时继承自date.prototype和object.prototype。这一系列链接的原型对象就是所谓的“原型链”(prototype chain)。
object.create()
创建一个新对象,其中第一个参数是这个对象的原型。object.create()提供第二个可选参数,用以对对象的属性进行进一步描述。
object.create()是一个静态函数,而不是提供给某个对象调用的方法。使用它的方法很简单,只须传入所需的原型对象即可:
var ab = object.create({x:1,y:2});
属性的查询和设置
var a = book.author; //得到book的"author"属性 book.edition = 6; //给book创建一个名为"edition"的属性并赋值 book["main title"] = "123" //给"main title"属性赋值
继承
假设要查询对象o的属性x,如果o中不存在x,那么将会继续在o的原型对象中查询属性x。如果原型对象中也没有x,但这个原型对象也有原型,那么继续在这个原型对象的原型上执行查询,直到找到x或者查找到一个原型是null的对象为止。
var o = {} o.x = 1;//给o定义一个属性x var p = inherit(o);//p继承o p.y = 2;//给p定义一个属性y var q = inherit(p);//q继承p q.z = 3;//给q定义一个属性z q.x + q.y // 3 x和y分别继承自o和p
属性赋值操作首先检查原型链,以此判定是否允许赋值操作。如果允许属性赋值操作,它也总是在原始对象上创建属性或对已有的属性赋值,而不会去修改原型链。
var u = { r:1 }; var c = inherit(u); c.x = 1; c.y =1; c.r =2; u.r; // 1 原型对象没有修改
属性访问错误
当book没有a属性
book.a // undefined var l = book.a.length; //抛出一个类型错误异常,undefined没有属性
删除属性
delete运算符可以删除对象的属性。
delete book.author; //book不再有属性author delete book["main title"]; //book不再有属性"main title"
delete运算符只能删除自有属性,不能删除继承属性(要删除继承属性必须从定义这个属性的原型对象上删除它,而且这会影响到所有继承自这个原型的对象)。
当delete表达式删除成功或没有任何副作用(比如删除不存在的属性)时,它返回true。如果delete后不是一个属性访问表达式,delete同样返回true:
o = {x:1}; delete o.x; //删除x,返回true delete o.x; //什么都没做(x已经不存在了),返回true delete o.tostring; //什么也没做(tostring是继承来的),返回true delete 1; //无意义,返回true
delete不能删除那些可配置性为false的属性
在这些情况下的delete操作会返回false:
delete object.prototype;//不能删除,属性是不可配置的 var x = 1; //声明一个全局变量 delete this.x; //不能删除这个属性 function f (){}//声明一个全局函数 delete this.f; //也不能删除全局函数
检测属性
in运算符的左侧是属性名(字符串),右侧是对象。如果对象的自有属性或继承属性中包含这个属性则返回true:
var o = { x:1 } "x" in o; //true "x"是o的属性 "y" in o; //false "y"不是o的属性 "tostring" in o; //true o继承tostring属性
对象的hasownproperty()方法用来检测给定的名字是否是对象的自有属性。对于继承属性它将返回false:
var o = { x:1 } o.hasownproperty("x");//true o有一个自有属性x o.hasownproperty("y");//false o中不存在属性y o.hasownproperty("tostring");//false tostring是继承属性
propertyisenumerable()是hasownproperty()的增强版,只有检测到是自有属性且这个属性的可枚举性(enumerable attribute)为true时它才返回true。
var o = inherit({ y:2}); o.x = 1; o.propertyisenumerable("x"); //true o有一个可枚举的自有属性x o.propertyisenumerable("y"); //false y是继承来的 object.propertyisenumerable("tostring"); //false 不可枚举
除了使用in运算符之外,另一种更简便的方法是使用“!==”判断一个属性是否是undefined:
var o = { x:1 } o.x !== undefined; //true o中有属性x o.y !== undefined; //false o中没有属性y o.tostring !== undefined; //true o继承了tostring属性
序列化对象
对象序列化(serialization)是指将对象的状态转换为字符串,也可将字符串还原为对象。ecmascript 5提供了内置函数json.stringify()和json.parse()用来序列化和还原javascript对象。这些方法都使用json作为数据交换格式,json的全称是“javascript object notation”
o = {x:1, y:{z:[false,null,""]}}; s = json.stringify(o); //s是'{"x":1,"y":{"z":[false,null,""]}}' p = json.parse(s); // p == o
总结
本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注的更多内容!
上一篇: 多功能便利柜“街柜”完成Pre-A轮融资
下一篇: 一篇文章带你了解C++的KMP算法