前言 这边整理一下几种创建对象的模式,并不存在哪个最好哪个不好之类的说法,每种模式都有着各自的优缺点及适用场景
先创建空Object对象,再动态添加属性/方法 适用于起始时不确定对象内部数据的场景 缺点:语句过多
- 代码例:
// Object构造函数,创建对象 let p = new Object() p.name = 'sky' p.age = 18 p.setName = function (name) { this.name = name } // 创建一个简单的对象,使用了4条语句使用 {} 创建对象,同时指定属性/方法 适用于起始时对象内部数据是确定的场景 优点:创建单个对象很方便 缺点:创建多个对象,则存在重复代码
一般情况下,这可能是大多数人用得最多的一种方法
- 代码例:
// 对象字面量,创建对象 let p1 = { name: 'sky', age: 18, setName: function(name) { this.name = name } } let p2 = { name: 'jack', age: 12, setName: function(name) { this.name = name } } // 创建一个简单的对象,只需使用一条语句 // 但是很明显,创建多个对象时,存在过多重复代码通过工厂函数动态创建对象并返回 适用于创建多个对象的场景 缺点:如果对象有种族或职业等差异,则无法区分对象的具体类型,因为都属于Object
这个模式用得相对少一些
- 代码例:
// 工厂模式,创建对象 function createPerson(name, age) { // 返回一个对象的函数,即为工厂函数 let obj = { name: name, age: age, setName: function(name) { this.name = name } } return obj } // 创建2个人 let p1 = createPerson('sky', 18) let p2 = createPerson('jack', 12) console.log(p1 instanceof Object) // true console.log(p2 instanceof Object) // true // p1和p2都属于Object,但是如果p1是教师,p2是学生,那么就无法区分了通过new 自定义构造函数 适用于需要创建多个类型确定的对象的场景 缺点:每个对象都有着相同的数据,浪费内存
- 代码例:
// 自定义构造函数,创建对象 // 创建构造函数(定义对象类型) function Teacher(name, age) { // 教师 this.name = name this.age = age this.setName = function (name) { this.name = name } } function Student(name, age) { // 学生 this.name = name this.age = age } let p1 = new Teacher('sky', 18) // 教师对象 let p2 = new Student('jack', 12) // 学生对象 console.log(p1 instanceof Teacher) // true p1是教师 console.log(p2 instanceof Student) // true p2是学生 // 如此一来便能区分,但同时这种方法也是存在缺点的 let p3 = new Teacher('tom', 25) // 教师对象 p3.setName('bob') // p3调用setName方法 console.log(p1) // 打印输出p1教师 // Teacher{name: 'sky', age: 18, setName: function(){...}} console.log(p3) // 打印输出p3教师 // Teacher{name: 'bob', age: 25, setName: function(){...}} // p1教师在创建时,并没有用到第三个参数,但是仍然还是创建出来给了p1,即便p1用不上 // 这样一来,用不到的属性/方法就占用着内存,显得浪费了自定义构造函数内,只写一些基本属性,额外方法添加至原型上 适用于需要创建多个类型确定的对象的场景
- 代码例:
// 自定义构造函数+原型对象,创建对象 // 创建构造函数(教师类型) function Teacher(name, age) { // 构造函数中放些初始化的属性 this.name = name this.age = age } // 给Teacher构造函数的显式原型上添加setName方法,以便实例对象使用 Teacher.prototype.setName = function (name) { this.name = name } // 创建两个教师对象 let p1 = new Teacher('sky', 18) let p2 = new Teacher('jack', 25) console.log(p1) // 打印输出p1教师 // Teacher{name: 'sky', age: 18} console.log(p2) // 打印输出p2教师 // Teacher{name: 'jack', age: 25} // 由于setName添加为了Teacher的原型方法,p1和p2各自本身就不携带这个方法了 // 谁想要使用,就调用一下 p1.setName('tom') console.log(p1) // Teacher{name: 'tom', age: 18}- Recorded by Scorpio_sky@2020-10-24
