发布于2026-07-22 阅读(0)
扫一扫,手机访问
对象直接量,说白了就是一个名/值对的映射表。写法上,名和值用冒号隔开,每一对之间用逗号分隔,整体用花括号包起来。看几个例子就明白了:
var empty = {};var point = { x:0, y:0};var point2 = {x:point.x, y:point.y+1};var book = {"main title":"Ja vaScript",//属性名字里有空格,必须用字符串表示"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对象
所有通过对象直接量创建的对象,其实都共享同一个原型对象——也就是 Object.prototype。而通过 new 关键字和构造函数创建的对象,它们的原型就是构造函数的 prototype 属性。举个例子:new Object() 创建的对象继承自 Object.prototype,new Array() 创建的对象继承自 Array.prototype,new Date() 则继承自 Date.prototype。
有一个特例:Object.prototype 本身没有原型,它不继承任何属性。但其他所有原型对象都是普通对象,它们都有自己的原型。比如 Date.prototype 继承自 Object.prototype,所以 new Date() 创建的对象既能访问 Date.prototype 上的属性,也能访问 Object.prototype 上的属性。这一连串的原型链接,就是所谓的“原型链”。
ES5 提供了一个静态方法 Object.create(),用来创建一个新对象,并指定它的原型。第一个参数就是原型对象,第二个可选参数可以用来进一步描述属性。用法很简单:
var AB = Object.create({x:1,y:2});
这样,AB 就继承了 {x:1,y:2} 这个对象。
属性读写的基本语法就不多说了,直接看例子:
var a = book.author;//得到book的"author"属性book.edition = 6;//给book创建一个名为"edition"的属性并赋值book["main title"] = "123"//给"main title"属性赋值
当你查询一个对象的属性时,如果它自身没有这个属性,Ja vaScript 会自动沿着原型链向上找。比如,查询对象 o 的属性 x,如果 o 里没有,就会看 o 的原型对象,如果原型里也没有,就继续往上,直到找到或者碰到原型为 null 为止。来看一段代码:
var o = {}o.x = 1;//给o定义一个属性xvar p = inherit(o);//p继承op.y = 2;//给p定义一个属性yvar q = inherit(p);//q继承pq.z = 3;//给q定义一个属性zq.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 原型对象没有修改
给 c 的 r 赋值为 2,但原型对象 u 的 r 仍然是 1,没有受到影响。
如果访问一个不存在的属性,会返回 undefined。但有个坑:如果试图访问 undefined 的某个属性,就会抛出类型错误。比如:
book.a // undefinedvar l = book.a.length;//抛出一个类型错误异常,undefined没有属性
delete 运算符可以删除对象的自有属性。注意,它只能删除自有属性,不能删除继承属性——要删继承属性,只能去定义它的原型对象上删,而且会影响所有继承自该原型的对象。
delete book.author;//book不再有属性authordelete book["main title"];//book不再有属性"main title"
delete 如果操作成功,或者操作本身没有意义(比如删除一个不存在的属性),它会返回 true。如果 delete 后面跟的不是属性访问表达式,也返回 true:
o = {x:1};delete o.x; //删除x,返回truedelete o.x; //什么都没做(x已经不存在了),返回truedelete o.toString; //什么也没做(toString是继承来的),返回truedelete 1; //无意义,返回true
但是,如果属性是不可配置的(configurable 为 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有一个自有属性xo.hasOwnProperty("y");//false o中不存在属性yo.hasOwnProperty("toString");//false toString是继承属性
还有一个更严格的 propertyIsEnumerable(),它除了要求是自有属性,还要求该属性是可枚举的(enumerable 为 true)才会返回 true:
var o = inherit({ y:2});o.x = 1;o.propertyIsEnumerable("x"); //true o有一个可枚举的自有属性xo.propertyIsEnumerable("y"); //false y是继承来的Object.propertyIsEnumerable("toString"); //false 不可枚举
当然,除了 in,还有一种更常见的方法:直接用 !== undefined 来判断属性是否存在:
var o = { x:1 }o.x !== undefined; //true o中有属性xo.y !== undefined; //false o中没有属性yo.toString !== undefined; //true o继承了toString属性
不过要注意,这种方法无法区分“属性不存在”和“属性存在但值就是 undefined”这两种情况。如果确实需要区分,还是用 in 更稳妥。
对象序列化,简单说就是把对象的状态转成字符串,反过来也能把字符串还原成对象。ES5 提供了两个内置函数:JSON.stringify() 和 JSON.parse()。它们都基于 JSON 格式(Ja vaScript 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
这样,对象就完成了序列化和反序列化,非常方便。
上一篇:JSP之EL表达式基础详解
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8