不管是哪门语言,千变万化不离其宗,深入理解其本质,方能应用自如。对应到js,闭包,原型,函数,对象等是需要花费大功夫思考、理解的。
这一次我们来说一说在JavaScript中经常会用到的一个复杂基本类型,对象,先从对象的属性讲起,再讲对象的创建方法,基本涵盖了创建对象的各种方法,大家一起学习呀~
一、对象
要掌握对象的使用及继承,首先当然需要先理解它,接下来,将会对对象的属性类型进行一个整理
1、什么是对象
对象其实是无序属性的集合,其属性可以包含基本值,对象或者函数,比如像下面这个例子就是一个person对象啦
var person = { name: "NIcholas", age: 29, sayName: function() { console.log(this.name); } }
从上面的例子我们可以看到,对象可以是由属性和其相应的值构成,对象中可以包含函数,也可以包含其它对象
2、属性类型
在JavaScript中,其实有两种属性,包括数据属性和访问器属性
(1)数据属性
数据属性包含一个数据值的位置,在这个位置可以读取和写入值,一般来说,有4个描述其行为的特性:
a、[[Configurable]]:表示能否通过delete删除属性从而重新定义属性,默认值为true
b、[[Enumerable]]:表示能否通过for-in循环返回属性,默认值为true
c、[[Writable]]:表示能否修改属性的值,默认值为true
d、[[Value]]:包含这个属性的数据值,默认值为undefined
一般来说,数据属性都有自己的默认值,那么如果我们要修改数据属性默认的特性,应该怎么办呢?这个时候就需要用到Object,defineProperty()方法啦,这个方法接收三个参数:属性所在的对象,属性的名字和一个描述对象,来看下面的例子
var person = {}; Object.defineProperty(person, "name", { writable: false, value: "Nicholas" }); console.log(person.name); // Nicholas // 重新赋值 person.name = "Greg"; console.log(person.name); // Nicholas
从上面的例子我们可以看到,因为设置了person对象的name属性为不可修改,因此无论你在后面怎么修改person的name属性的值,name属性的值都不会发生改变
(2)访问器属性
访问器属性不包含数据值,它们包含一对儿getter和setter函数,在读取访问器属性时,会调用getter函数,这个函数负责返回有效的值,在写入访问器属性时,会调用setter函数并传入新值,这个函数负责决定如何处理数据,访问器属性有以下4个特性
a、[[Configurable]]:表示能否通过delete删除属性从而重新定义属性,默认值为true
b、[[Enumerable]]:表示能否通过for-in循环返回属性,默认值为true
c、[[Get]]:在读取属性时调用的函数,默认值为undefined
d、[[Set]]:在写入属性时调用的函数,默认值为undefined
访问器属性不能直接定义,必须调用Object.definedProperty()来定义的,来看下面的例子
var book = { _year:2004, edition:1 } Object.defineProperty(book, "year", { get: function() { return this._year; }, set: function(newValue) { this._year = newValue; } });
这里要说明一下,book对象中_year前面的下划线是一种常用的记号,用于表示只能通过对象方法访问的属性,还有呀,大家不要小看了Object.definedProperty()这个方法,这个方法可是很强大呀,像vue的双向数据绑定,其实就是用到了这个方法去实现的
(3)读取属性的特性
既然JavaScript有数据属性和访问器属性,那么我们怎样才能读取它们呀,这个时候就需要用到Object.getOwnPropertyDescriptor()方法了,这个方法可以取得给定属性的描述符,接收两个参数,分别是属性所在的对象和要读取其描述符的属性名称
二、对象的创建
在了解了对象之后,接下来我们就需要说下怎么创建对象了,最简单的方法,当然就是使用前面说的对象字面量的方法去创建啦,但是如果我们需要创建好多个对象,用前面的方法就不行了,我们需要用到其它更加简便的方法,帮助我们创建出多个对象
1、工厂模式
这种模式其实是一个设计模式,抽象了创建具体对象的过程,主要是通过在函数内部创建一个对象,为其添加属性和方法,并将对象返回,从而实现创建多个对象的目的,来看下面的例子
function createPerson(name, age) { var o = new Object(); o.name = name; o.age = age; o.sayName = function() { console.log(this.name); }; return o; } var person1 = createPerson("Nicholas", 29); var person2 = createPerson("Greg", 27);
优点:能够解决创建多个对象的问题,兼容各个浏览器
缺点:没有解决对象识别的问题,不能知道一个对象的类型
2、构造函数模式
这种模式主要通过创建自定义的构造函数,从而定义自定义对象类型的属性和方法,来看下面例子