JS小红书-对象创建的几种模式
个人觉得这趴比较难以消化和理解,也比较拗口。首先总结一波,创建对象有以下几种模式:
- 工厂模式
- 构造函数模式
- 原型模式
- 组合使用构造函数模式和原型模式
- 动态原型模式
- 寄生构造函数模式
- 稳妥构造函数模式
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('jack',18)
var person2=createPerson('tom',20)
优点
解决了创建多个相似对象的问题
缺点
没有解决对象识别问题,即 怎样知道一个对象的类型
2.构造函数模式
function Person(name,age){
this.name = name
this.age = age
this.sayName = function(){
console.log(this.name)
}
}
var person1 = new Person('jack','14')
var person2 = new Person('tom','15')
构造函数模式相比工厂模式,主要的区别有:
- 没有显示的创建对象
- 直接将属性和方法赋值给了this对象
- 没有return 语句
顺便总结一波,
new操作符干了什么
function _new(fn,...args){
//创建一个空对象
const obj = {}
//将对象的隐式原型对象指向构造函数的原型对象
obj.__proto__ = fn.prototype
//绑定this
fn.apply(obj,args)
//返回该对象
return obj
}
优点
可以标识成一个特定的类型,属性私有
缺点
函数也变成私有的,无法共享,每个方法都要在每个实例上创建一遍
3.原型模式
function Person(){}
Person.prototype.name = 'jack'
Person.prototype.age = 18
Person.prototype.sayName = function(){
console.log(this.name)
}
var person1 = new Person()
person1.sayName() //jack
var person2 = new Person()
person2.sayName() //jack
优点
实现方法共享
缺点
属性也共享了,修改一个实例的属性会改变另一个实例对象,不支持传参
4.组合使用构造函数模式和原型模式
function Person(name,age){
this.name = name
this.age = age
}
Person.prototype.sayName = function(){
console.log(this.name)
}
var person1 = new Person('jack',14)
var person1 = new Person('tom',18)
优点
属性私有,方法共享,最大限度的节省了内存,还支持向构造函数传参
5.动态原型模式
function Person(name,age){
this.name = name
this.age = age
if(typeof this.sayName !== 'function'){
Person.prototype.sayName = function(){
console.log(this.name)
}
}
}
优点
把构造函数和原型都封装在一起,且只有在初始化时才会对原型进行操作
6.寄生构造函数模式
function SpecialArray(){
//创建数组对象
var values = new Array()
//添加值
values.push.apply(values,argemunts)
//添加方法
values.toPipedString = function(){
return this.join('|')
}
}
var colors = new SpecialArray('red','blue','green')
console.log(colors.toPipedString()) // 'red|blue|green'
场景
如上图,创建一个具有额外方法的特殊数组。
7.稳妥构造函数模式
function Person(name,age){
var o = new Object()
o.sayName = funcion(){
console.log(name)
}
return o
}
var person = Person('jack',15)
person.sayName() // 'jack'
场景
在一些严格模式下,不能使用this、new ,且变量私有不允许别的方式访问到其数据成员