JS创建对象的十种方式总结
作者:爱吃糖的猫
面向对象是一种重要的编程范式,如何灵活的创建对象,是对编程基本功的考验,本来我们来探讨一下JavaScript中创建对象的十种方式,感兴趣的小伙伴可以了解下
前言
面向对象是一种重要的编程范式,如何灵活的创建对象,是对编程基本功的考验,本来我们来探讨创建对象的十种方式。我将这十种分为new Object
、构造函数与原型对象、其他三个大类。
new Object
这三种本质都是new Object
,他们无法根据对象的原型对象准确判断对象的类型,因为原型对象上都是Object。console.log(obj.__proto__===Object.prototype); // true
new Object
const obj = new Object({name: 'wayne',age: 18})
字面量方式
const obj = {name: 'wayne',age: 18}
工厂函数方式
function createPerson(name, age) { return {name,age,} } const obj = createPerson('wayne', 18)
构造函数与原型对象
这四种是对构造函数与原型对象创建对象上的细化。
构造函数方式
如果构造函数中包含的方法,则会重复创建,造成内存的浪费(只适合放属性不适合方法)
function Person(name, age) { this.name = name this.age = age this.getInfo = function() { console.log(this.name, this.age) } } const obj = new Person('wayne', 18)
原型对象方式
合放方法:将共同的方法放到原型当中可以避免重新创建相同功能的方法,减少了内存的使用。 不适合放属性:原因有三条
- new初始化新的属性时候不方便,
- 修改起来不方便
p1.__proto__.name = 'jack'
- 在原型对象的属性会在所有的对象上共享,导致新new出来出现问题
function Person() {} Person.prototype.name = "wayne" Person.prototype.age = 10 Person.prototype.getInfo = function() { console.log(this.name, this.age) } const p1 = new Person() // 这里使用的是原型上的属性 p1.getInfo() // wayne 10 // 修改原型上的属性 p1.__proto__.name = 'jack' p1.__proto__.age = 18 // 这里使用的是原型上的属性 p1.getInfo() // jack 18 const p2 = new Person() // 修改过的属性 p2.getInfo() // jack 18
混合模式
这是我们常见的方式,将属性放在构造函数,方法放在原型上。但这种方式不太符合面向对象封装的思想。
function Person(name, age) { this.name = name this.age = age } Person.prototype.getInfo = function() { console.log(this.name, this.age) } const p1 = new Person(name, age)
动态混合
其实就是混合模式的改进,这种方式的缺点是语义不符,其实只有第一个对象创建时才会走 if 判断
function Person(name, age) { this.name = name this.age = age if (Person.prototype.getInfo === "undefined") { Person.prototype.getInfo = function() { console.log(this.name, this.age) } } } // 第一次调用时会给 Person.prototype 添加 getInfo 方法 const p1 = new Person("wayne", 18) const p2 = new Person("jack", 15)
寄生构造函数
和动态混合一样,但通过函数里调用其他构造函数
function Person(name, age) { this.name = name this.age = age if (Person.prototype.getInfo === "undefined") { Person.prototype.getInfo = function() { console.log(this.name, this.age) } } } function func(name, age) { const p = new Person(name, age) return p } const p1 = func("wayne", 18)
其他
class
使用ES6语法糖class创建对象,其实class的本质就是function。
class Person { constructor(name, age) { this.name = name this.age = age } getInfo() { console.log(this.name, this.age) } } const p1 = new Person("wayne", 18) // class的本质是function console.log(typeof Person); //function
闭包
利用闭包的特性,也可以实现创建对象。优点:不用this 和 new;缺点:容易造成内存泄漏。
function Person(name, age) { return { getName() { return name }, getAge: function() { return age } } } const p1 = Person("wayne", 18) console.log(p1.getName()) // wayne console.log(p1.getAge()) // 18
总结
new Object的三种
new Object
:new Object({name: 'wayne',age: 18})
- 字面量创建:
{name: 'wayne',age: 18}
- 工厂函数方式:
function createPerson(name, age) {return {name,age,}}
构造函数与原型对象四种
- 构造函数方式:适合属性
- 原型对象方式:适合方法
- 混合方式:常见的方式,将属性放在构造函数,方法放在原型上。
- 动态混合:使用if判断是否挂载方法
- 寄生构造函数:通过函数里调用其他构造函数
其他两种
- class,ES6语法糖,本质为function
- 闭包:优点:不用this 和 new;缺点:容易造成内存泄漏。
以上就是JS创建对象的十种方式总结的详细内容,更多关于JS创建对象的资料请关注脚本之家其它相关文章!