1.工厂模式
用函数来封装创建对象
创建出来的对象无法和某个类型联系起来(就是怎样知道一个对象的类型是什么)
function createPerson(name, age, job){
let tuple = new Object()
tuple.name = name
tuple.age = age
tuple.job = job
tuple.sayName = function(){
alert(this.name)
}
return tuple
}
let origins = createPerson('names', 16, 'job')
2.构造函数 (new)
执行构造函数首先会创建一个对象,然后将对象的原型指向构造函数的 prototype 属性,然后将执行上下文中的 this 指向这个对象,
最后再执行整个函数,如果返回值不是对象,则返回新建的对象。因为 this 的值指向了新建的对象,因此我们可以使用 this 给对象赋值
造成了不必要的函数对象创建( 对象属性如果包含函数,每次都会新建一个函数对象, 浪费了内存空间 )
3.原型模式 (prototype & new实例化)
每个函数都有prototype属性对象.它包含了通过构造函数创建的所有实例都能共享的方法和属性,我们可以使用原型对象来添加公用属性和方法
无法通过传入参数来初始化,以及如果存在引用类型,一个实例对引用类型的修改会影响所有实例
4.构造函数 + 原型模式
用构造函数来初始化对象的属性,通过原型对象来实现函数方法的复用
因为使用了两种不同的模式,所以对于代码的封装不够好
function Person(name, age, job){
this.name = name
this.age = age
this.job = job
}
Person.prototype = {
constructor: Person,
sayName: function(){
alert(this.name)
}
}
let person1 = new Person('name', 23, 'book')
5.动态原型模式
将原型赋值的创建过程移动到了构造函数内部,通过判断属性是否存在,可以实现仅在第一次调用函数时对原型对象赋值的一次效果
function Person(name, age, job){
this.name = name
this.age = age
this.job = job
if(typeof this.sayName !== 'function'){
Person.prototype.sayName = function(){
alert(this.name)
}
}
}
let person2 = new Person('namess', 23, 'book')
6.寄生构造函数
和工厂函数实现基本相同,主要基于一个已有的类型,在实例化时对实例化的对象进行扩展(既可不修改原先的构造函数,也达到了扩展目的)
缺点和工厂模式一样,无法实现对象的识别
function Person(name){
let dict = new Object()
dict.name = name
dict.sayName = function(){
alert(this.name)
}
return dict
}
let person3 = new Person('rainy')