JavaScript中的对象学习笔记(概述和创建)

242 阅读6分钟

本文是笔者学习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实际上对应的是同一个对象引用,因此修改任意一个,都会对对象产生影响。
    	 
    
  • 常用的对象用法(之后会分节讨论)

    1. 创建(create)
    2. 设置(set)
    3. 查找(query)
    4. 删除(delete)
    5. 检测(test)
    6. 枚举(enumerate)

二. 属性的重点

  • 属性的键是包含空字符串在内的任意字符串,且同一个对象内,不能存在相同的键。

  • 属性可以是任意js支持的值,或者在ES5标准下可以是一个getter和setter的函数(之后会有这两个函数的讨论)。

  • 除了名字和值之外,每个属性还有一些羽织相关的描述值,称为属性特性(property attribute),分别是:

    1. 可写(writable attribute),表明是否可以设置该属性的值
    2. 可枚举(enumerable attribute),表明是否可以通过for循环遍历到该属性
    3. 可配置(configurable attribute),表明是否可以删除或者修改该属性。
  • 在es5之前,通过代码给对象创建的属性都是可写、可枚举和可配置的,在es5种可以对这些特性进行配置(之后会讨论)。

  • 除了包含普通属性之外,每个对象还包含三特相关特性(object attribute)

    1. 对象的原型(prototype),指向一个对象,本对象可以继承该对象的属性。
    2. 对象的类(class),标识对象类型的字符串。
    3. 对象的扩展标记(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" 
		}
	}

注意:

  1. 在ES5中,保留字可以用作不带引号的属性名。但是对于大部分的ES3实现,保留字作为属性名必须用引号引起来。
  2. 在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()不能接受第二个参数。

概述和创建对象的重点记录到这里,下一节将更关注对象本身的操作,我会不定期补充知识点和注意事项。