本文是笔者学习JavaScript时做的笔记,大部分内容来自《JavaScript权威指南》,记录学习中的重点,并引入一些其他博文和与其他程序员讨论的内容,供本人日常翻阅。如有疑问,请留言评论,对本文的内容想深入了解,请支持并购买正版《JavaScript权威指南》。
一. 概述
对象是JavaScript(之后简称js)的基本类型之一。以下为Object的一些基本知识(随时更新)。
-
其形式是属性(键/值对)的合集,属性名是字符串,可以看做是字符串到值的映射合集。
-
这种基本数据结构也被称为,散列(hash)、散列表(hashtable)、字典(dictionary)、关联数组(associative array)
-
对象最重要的特征是可以从一个被称为原型的对象那里继承属性,这种原型式继承(prototypal inheritance)js的核心特征。
-
对象是_可变的_,js中声明一个对象时,是通过引用而不是通过拷贝一个副本,如下所示。
var obj = { x:1 }; console.log(obj); //打印{x:1} var obj_c = obj; obj.x = 5; console.log(obj_c); //打印{x:5} obj_c.x = 2; console.log(obj); //打印{x:2} //obj和obj_c实际上对应的是同一个对象引用,因此修改任意一个,都会对对象产生影响。 -
常用的对象用法(之后会分节讨论)
- 创建(create)
- 设置(set)
- 查找(query)
- 删除(delete)
- 检测(test)
- 枚举(enumerate)
二. 属性的重点
-
属性的键是包含空字符串在内的任意字符串,且同一个对象内,不能存在相同的键。
-
属性可以是任意js支持的值,或者在ES5标准下可以是一个getter和setter的函数(之后会有这两个函数的讨论)。
-
除了名字和值之外,每个属性还有一些羽织相关的描述值,称为属性特性(property attribute),分别是:
- 可写(writable attribute),表明是否可以设置该属性的值
- 可枚举(enumerable attribute),表明是否可以通过for循环遍历到该属性
- 可配置(configurable attribute),表明是否可以删除或者修改该属性。
-
在es5之前,通过代码给对象创建的属性都是可写、可枚举和可配置的,在es5种可以对这些特性进行配置(之后会讨论)。
-
除了包含普通属性之外,每个对象还包含三特相关特性(object attribute)
- 对象的原型(prototype),指向一个对象,本对象可以继承该对象的属性。
- 对象的类(class),标识对象类型的字符串。
- 对象的扩展标记(extensible flag)指明是否可以向该对象添加新的属性。
三. 创建对象
(一)对象直接量
对象直接量,是指在js代码中,用大括号将键值对包含在一起,属性之间用逗号隔开,键值对用冒号连接的形式直接创建一个对象。
对象直接量是一个表达式,这个表达式运算过程中,会创建并初始化一个新的对象。
var empty = {}; //没有任何属性的对象
var point = { x:0,y:0} //两个属性
var point2 = {x:point.x, y:ponit.y+1} //更多属性
var book = {
"main title":"JavaScript", //字符串中可以带空格
"sub-title":"The Defintitive Guide", //属性名字里有-
"for":"all audiences", //"for"是保留字,必须用引号
author:{ //单纯属性名可以不用引号
firstname:"David"
}
}
注意:
- 在ES5中,保留字可以用作不带引号的属性名。但是对于大部分的ES3实现,保留字作为属性名必须用引号引起来。
- 在ES5&ES3的大部分实现中,对象直接量最后一个逗号会被忽略,但是ie中会报错。
(二)通过new创建对象
new云算符创建并初始化一个新对象,关键字new后跟随一个函数调用。这里的函数即是构造函数(constructor)。js语言核心包含内置构造函数
var o = new Object();//创建一个空对象,和{}作用相同
var a = new Array();//创建一个空数组,和[]作用相同
var d = new Date();//创建一个表示当前时间的Date对象
var r = new RegExp("js");//创建一个进行模式匹配的RegExp对象
(三) 通过Object.create()创建
1.原型 在介绍Object.create()之前,先要了解一下原型的概念。 每个js中的对象(除了null)都与一个对象相关联,这个关联的对象就是原型,每个对象都从原型中继承属性。
- 所有通过对象直接量创建的对象都具有同一个原型对象,并通过js代码Object.prototype获得该对象的引用。
- 通过关键字new和构造函数调用创建的对象的原型就是构造函数的prototype属性的值。
- js实现中,大部分对象都有原型,Object.prototype就是其中之一。
- 一个对象往上查找,会有一个连续继承的原型结构,这个就是是所谓的原型链。
2.Object.create()
ES5中定义了Object.create()的方法,它创接受两个参数,第一个参数是这个对象的原型,第二个可选参数用以描述本对象。本函数是一个静态函数。
var o1 = Object.create({x:1,y:2});
//o1将继承x和y这两个属性。
Object.create()通过传入null,可以创建一个没有原型的,真正意义上的空对象,该对象不会继承任何东西,甚至不包括基本方法,如toString(),如果想创建一个普通的空对象,则必须传入Object.prototype
var o3 = Object.create(Object.prototype);
//如此创建的o3行为和{}和new Object()完全一样。
Object可以通过原型创建对象,也就是说,你可以通过这个方法,创建一个继承任意对象的对象,不过这个方法来自es5标准,在某些es3实现中,可以用如下方法模拟:
function inherit(p){ //inherit即为继承,参数为要继承的原型
if(p==null) throw TypeError(); //p不能是null
if(Object.create) //如果支持Object.create的话直接调用
return Object.create(p);
var t = typeof p;
if(t!=="object"&&t!=="function") throw TypeError(); //否则进一步检测
function f(){}; //定义一个空的构造函数f
f.prototype = p; //将f的构造函数设置为p
return new f(); //使用f()创建p的继承对象
}
当然这个方法并不完善,第一inherit()不能接受null,第二inherit()不能接受第二个参数。
概述和创建对象的重点记录到这里,下一节将更关注对象本身的操作,我会不定期补充知识点和注意事项。