JavaScript创建对象的方式

编写代码过程中随时有创建对象的需要,不经意间就创建了一个对象。创建对象有很多方式,这里就我目前了解到的方式进行梳理。
先介绍3种基础的方式,并加上工厂模式的改进。后续再就原型、继承等概念进行展开,会有更多创建对象的方式。
一、字面量
字面量是指某种数据的典型的、直观的形式,数组的形式是[],对象的形式是{}。
使用对象字面量创建对象,{}内使用“键:值”的格式,代码如下:

var obj = { name: 'bencjl', age: 19, sayHi: function () { console.log('hi'); } } console.log(obj);

二、内置Object类
Object类是JavaScript内置的类,而且所有对象的最终原型都是Object。
这里先使用构造函数Object()创建了对象,然后再逐个属性赋值。代码如下:
var obj = new Object(); obj.name = 'bencjl'; obj.age = 19; obj.sayHi = function() { console.log('hi'); } console.log(obj);

另外,Object()构造函数还可以接受一个对象作为参数。如果参数是一个对象字面量,写法接近上面字面量创建对象的写法了;如果参数是一个对象的变量名,返回的还是这个变量的引用地址,没有什么意义。
三、构造函数
Object对象是通过Object()构造函数创建的。同样道理,我们也可以自定义构造函数,创建自定义的对象。
function ObjFunc() { this.name = 'bencjl'; this.age = 19; this.sayHi = () => { console.log('hi'); } } var obj = new ObjFunc(); console.log(obj);

这里要夹带两个“私货”:
(1) console打印出来,有个标记是ObjFunc,而前面两种方法没有这个标记。这个ObjFunc标记说明这是一个自定义的类(的对象),不是Object类(的对象)。
(2) 前面的代码,sayHi()都是用匿名函数格式function(){},这里sayHi()使用了箭头函数的格式()=>{}。
四、改进:字面量 + 工厂模式
不管是字面量还是内置Object类,前面的写法都只能写一堆代码、创建一个对象。如果需要大量、反复创建对象怎么办?这时就要复用代码,要包装成函数。(构造函数的方式已经是函数的方式了)
这就是工厂模式的一种代码实现,包装成函数之后可以不断调用、批量生产对象。代码如下:
function createObject(name, age, sayHi) { return { name, age, sayHi } } var obj = createObject('bencjl', 19, () => { console.log('hi'); }); console.log(obj);

这里又夹带了“私货”:
(1) 函数当然可以传递参数,这里“工厂函数”写成传递参数的形式,调用函数创建对象时才传入自定义的参数。
(2) “工厂函数”返回的对象字面量,没有使用“键:值”格式。因为ES6支持这种简写的形式,只要属性名和赋值变量名字一样就行。这个简写的特性一般用在对象字面量中,其他方式套用不了。这里相当于属性名是“name”、属性值等于变量name,非简写形式就是“name: name”。
五、改进:内置Object类 + 工厂模式
将创建对象的代码包装成函数没有什么复杂的:
function createObject({ sayHi, age = 19, name }) { var o = new Object(); o['name'] = name; o['age'] = age; o['sayHi'] = sayHi; return o; } var obj = createObject({ name: 'bencjl', sayHi: () => { console.log(); } }); console.log(obj);

【JavaScript创建对象的方式】除了方括号[]访问形式,这里主要夹带的“私货”是解构赋值:
首先这个函数本质上是要接受一个对象作为参数的,而不是具体的name、age作为参数,调用时传递的实参也确实是一个对象。
其次,在参数列表中顺便做了结构赋值,并支持age默认值,不需要再到函数体中用中间变量接收、判断参数默认值。
最后,参数这种写法有什么好处?和第四部分相比,这种写法用属性名来对应匹配、赋值,不需要记住参数的先后顺序。

    推荐阅读