js创建对象__学习笔记:工厂模式、构造函数模式、原型模式
单纯的new Object会编写很多重复的代码
1. 工厂模式
用于抽象创建特定对象的过程。(不再自己一个个创建对象,而是通过函数创建对象)
function createPerson(name){
let obj = new Obeject()
obj.name = name
return obj
}
🔔关键点:在函数内部创建一个对象,最后再返回该对象
🙅♀️缺点:没有解决对象标识问题(即新创建的对象是什么类型的,instanceof无法识别)
2. 构造函数模式
构造函数,是特殊的函数,用于创建特定类型对象,以函数的形式为自己的对象类型定义属性和方法
🆚与工厂模式相比:1⃣️没有显示的创建对象、2⃣️属性与方法直接赋值给this、3⃣️没有return
🆚与普通函数相比:调用方式不同(如果不用new将会绑在window上,其他则绑定在this指向哪个对象上)
构造函数后面的括号可加可不加,如果没有传参可以不写
function Person(name){
this.name = name
this.sayName = fucntion(){
console.log(this.name)
}
}
let person1 = new Person('lala')
- 使用new操作符,会执行如下操作:
- 在内存中创建一个新对象
- 这个新对象的]__proto__指向构造函数的prototype
- 构造函数内部的this被复制为实例化的新对象
- 执行构造函数内部代码
- 返回对象
🔔关键点:使用构造函数,this赋值
✅好处:实例可以被标识为特定类型
🙅♀️缺点:构造函数定义的方法会在每个实例上都创建一遍,每个实例内都不是同一个function实例
因为方法都是做的一样的事情,this对象可以将函数与对象的绑定推迟在运行时==>可以把函数定义转移到构造函数外部
function Person(name){
this.sayName = sayName //包含的只是一个指向外部函数的指针,所以实例共享了函数
}
function sayName(){
console.log(this.name)
}
🙅♀️缺点:如果需要多个方法,就需要在全局作用域定义多个函数,代码不能很好的聚集在一起,全局作用于搞乱
**3. 原型模式 **
原型:每个函数都有prototype属性,这个属性是一个对象,对象包含特定类型的实例共享的属性和方法
使用原型对象的好处是,在它上面定义的属性和方法都可以被对象实例共享
function Person(){}
Person.prototype.name = 'Meng'
Person.prototype.sayName = function(){...}
let person1 = new person()
🆚与构造函数不同,使用这种原型模式定义的属性和方法是由所有实例共享的
🙅♀️缺点:任何时候对原型对象的修改都会在实例中反应出来,所有属性共享,引用值属性没有自己的属性副本
(原型上的引用值属性会一起都变,普通值类型不会相互影响)
弱化了向构造函数传递初始化参数的能力
- 原型:创建函数就会有prototype,所有原型对象自动获得constructor属性,指回构造函数 Person.prototype.constructor == Person
- 实例__proto__赋值为构造函数的原型对象
- 实例与构造函数无直接关系
- 沿着原型链寻找属性和方法,实例的同名属性可以遮蔽原有的 API
- Object.getPrototypeOf可以返回参数的__proto__
- Object.setPrototypeOf可以重写实例私有属性,严重影响代码性能
- Object.create创建新对象,同时可以指定原型
- hasOwnPrototype可以判断在实例上还是在原型上
- in操作符,只要有该属性则为true(可以单独使用,也可以for in)
- Object.keys返回所有可枚举属性名称的字符串数组
- Object.values返回内容数组
- Object.entries返回键值对数组
⚠️如果构造函数的prototype被重写(比如用声明式再赋值),则constructor属性不指回,可以在prototype内专门绑定