js中创建对象的几种方式

js中创建对象的几种方式

显式的创建 Object实例

使用 new操作符和Object构造函数
let person = new Object()

person.name = '张三'
person.age = 20
对象字面量表示法
let person = {
    name:'张三',
    age:20
}

虽然使用Object构造函数或者对象字面量可以方便的创建对象,但这些方式也有明显的不足,创建具有同样接口的多个对象需要重复编写很多代码

工厂模式

工厂模式是一种众所周知的设计模式,广泛应用于软件工程领域,用于抽象创建特定对象的过程

/**
 * 工厂模式创建对象
 **/
function createPerson(name,age,job){
    let p = new Object()
    p.name = name
    p.age = age
    p.job = job
    p.sayName = function(){
        console.log(this.name)
    }

    return p
}

let person1 = createPerson('张三',20,'开发')

let person2 = createPerson('李四',18,'测试')

函数createPerson接收3个参数,根据这几个参数构建了一个包含Person信息的对象。可以用不同的参数多次调用这个函数,每次都会返回包含3个属性和一个方法的对象。

工厂模式虽然可以解决创建多个类似对象的问题,但没有解决对象标识问题(即新创建的对象是什么类型的)

构造函数模式

/**
 * 构造函数模式
 */
function Person(name,age,job){
    this.name = name
    this.age = age
    this.job = job
    this.sayName = function(){
        console.log(this.name)
    }
}

//创建Person实例

let person1 = new Person('张三',20,'开发')

let person2 = new Person('李四',20,'测试')
构造函数与工厂模式的区别
  • 没有显示的创建对象
  • 属性和方法直接赋值给了this
  • 没有return
要创建Person的实例,应使用new操作符,以这种方式调用构造函数,会执行如下操作
  • 在内存中创建一个新的对象
  • 这个对象内部的[[Prototype]]特性被赋值为构造函数的prototype属性
  • 构造函数内部的this被赋值为这个新对象(即this指向新对象)
  • 执行构造函数内部的代码(给新对象添加属性)
  • 如果构造函数返回非空对象,则返回该对象,否则,返回刚创建的对象

自定义构造函数可以确保实例被标识为特定类型

原型模式

每个函数都会创建一个prototype属性,这个属性是一个对象,包含应该由特定引用类型的实例共享的属性和方法。实际上,这个对象就是通过调用构造函数创建的对象的原型。使用原型对象的好处是,在它上面定义的属性和方法可以被对象实例共享。

/**
 * 原型模式
 */
function Person(){

}

Person.prototype.name = '张三'
Person.prototype.age = 20
Person.prototype.job = '开发'
Person.prototype.sayName = function(){
    console.log(this.name)
}

let person1 = new Person()

这里,所有的属性和方法都直接添加到了Person的prototype属性上,构造函数体中什么也没有,这样定义之后,调用构造函数创建的新对象仍然拥有相应的属性和方法,与构造函数模式不同,使用这种原型模式定义的属性和方法是所有实例共享的。

对象迭代

ECMAScript 2017新增了两个静态方法,用于将对象内容转换为序列化的——更重要的是可迭代的格式,这两个静态方法Object.values()Object.entries()接收一个对象,返回他们内容(可枚举属性,不包括原型链)的数组,Object.values()返回对象(可枚举属性,不包括原型链)的数组,Object.entries()返回键/值对的数组。

let person = {
    name:'张三',
    age:20,
    job:{
        name:'开发'
    }
}

console.log(Object.values(person)) // ['张三',20,{name:'开发'}]

console.log(Object.entries(person)) // [['name','张三'],['age',20],['job',{name:'开发'}]]