虽然new Object( )和对象字面量的都可以用来创建单个对象,但有个缺点:如果使用同一接口创建许多对象,那么会产生冗余代码。

一、工厂模式

function createPerson(name, age, job) {let person = new Object();person.name = name;person.age = age;person.job = job;person.sayName = () => {console.log(this.name);};return person;
};
let person1 = createPerson('cc', 22, 'worker');
复制代码

缺点:虽然解决了代码冗余的问题,但无法识别每个对象的类型

二、构造函数模式

function Person(name, age, job) {this.name = name;this.age = age;this.job = job;this.sayName = () => {console.log(this.name);};
};
let person1 = new Person('cc', 22, 'worker');
console.log(person1.constructor === Person); //true
console.log(person1 instanceof Person);//true
复制代码

以这种方式创建的对象实际上经历了4个过程:

  1. 创建一个对象
  2. 将构造函数中的this指向该对象
  3. 执行构造函数(为该对象添加属性和方法)
  4. 返回该对象

通过构造函数创建的对象有个constructor属性(该属性在对象的_proto_即原型中,指向构造函数)。 如果要检测对象的类型,instanceof是操作符最为靠谱

缺点:每个方法都要在每个对象上重新创建一遍,对象之间不会共享方法,造成了内存空间的浪费,以下代码证明了这一点

let person1 = new Person('cc', 22, 'worker');
let person2 = new Person('bb', 22, 'coder');
console.log(person1.sayName === person2.sayName); //false
复制代码

三、原型模式

我们创建的每个函数都会自动有一个prototype属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。(prototype就是通过调用构造函数而创建的那个对象实例的原型对象)。prototype中又会自动生成一个constructor属性,该属性指向我们创建的那个函数。我们通过该函数创建的实例中也会自动生成一个指向prototype的指针[[Prototype]](这个属性一般不能访问,但在浏览器的实现里,该属性可以访问,通常为__proto__)
使用原型对象的好处是。换句话说,不必在构造函数中定义对象实例的信息,而是可以将这些信息直接添加到原型对象中。

以下为代码实现

function Person(){
}Person.prototype.name="cc";
Person.prototype.age=22;
Person.prototype.job="worker";
Person.prototype.sayName=function(){console.log(this.name)
};let person1=new Person();
person1.sayName();//cc
复制代码

更常见的做法是用一个包含所有属性和方法的对象字面量来重写整个原型对象,并重设constructor属性。

function Person(){
}Person.prototype={name:"cc",age:22,job:"worker",sayName:function(){console.log(this.name)}
};Object.defineProperty(Person.prototype,"constructor",{enumerable:false,value:Person,
});
复制代码

单独使用原型的弊端:
省略了为构造函数传递初始化参数这一环节,结果所有实例在默认情况下都将取得相同的属性值,虽然这会在一定程度带来一定的不便,但不是最大的问题,最大的问题是由其共享的本性所决定的。对于包含引用数据类型的值来说,会导致问题。(例如数组,如下修改person1的friends导致person2的friends也发生变化)

Person.prototype = {name: 'cc',age: 22,job: 'worker',friends: ['aa', 'bb', 'dd']
};Object.defineProperty(Person.prototype, 'constructor', {enumerable: false,value: Person
});
let person1 = new Person();
let person2 = new Person();
person1.friends.push('ff');
console.log(person1.friends); //aa,bb,dd,ff
console.log(person2.friends); //aa,bb,dd,ff
复制代码

四、组合使用构造函数和原型模式

这是创建自定义类型的最常见的方式。构造函数模式用于定义实例属性,而原型模式用于定义方法和共享的属性。所以每个实例都会有自己的一份实例属性的副本,但同时共享着对方法的引用,最大限度的节省了内存。同时支持向构造函数传递参数。

function Person(name,age,job){this.name=name;this.age=age;this.job=job;this.friends=["aa","bb"];
}Person.prototype={constructor:Person,sayName:function(){console.log(this.name);}
};let person1=new Person('cc',22,'worker');
复制代码

五、动态原型模式

function Person(name,age,job){this.name=name;this.age=age;this.job=job;if(typeof this.sayName!="function"){Person.prototype.sayName=function(){console.log(this.name);};}
}
复制代码

这里只有sayName()不存在的情况下,才会将它添加到原型中,这段代码只会在初次调用构造函数时才执行。这里对原型所做的修改,能够立刻在所有实例中得到反映。

六、寄生构造函数模式和稳妥构造函数模式

寄生构造函数模式和不太常见,所以在这里不赘述

javascript中创建对象的几种方式相关推荐

  1. 12月18日云栖精选夜读 | Java 中创建对象的 5 种方式!...

    作为Java开发者,我们每天创建很多对象,但我们通常使用依赖管理系统,比如Spring去创建对象.然而这里有很多创建对象的方法,我们会在这篇文章中学到. Java中有5种创建对象的方式,下面给出它们的 ...

  2. Java中创建对象的几种方式

    Java中创建对象的几种方式 1.使用new创建对象,在堆上创建. 2.克隆 3.反序列化 4.反射创建对象 5.NIO中可以使用本地方法直接分配堆外内存. 转载于:https://www.cnblo ...

  3. Java中创建对象的四种方式

    为什么80%的码农都做不了架构师?>>>    Java中创建对象的四种方式 (1) 用new语句创建对象,这是最常见的创建对象的方法.    (2) 运用反射手段,调用java.l ...

  4. 【JavaScript】创建对象的三种方式

    JavaScript创建对象的三种方式 1.调用系统的构造函数创建对象2.自定义构造函数创建对象(结合第一种和需求通过工厂模式创建对象)3.字面量的方式创建对象 一.调用系统的构造函数创建对象 举个栗 ...

  5. JS中创建对象:三种方式(pink)

    在 JavaScript 中,现阶段我们可以采用三种方式创建对象(object): (1)利用字面量创建对象 (2)利用new Object创建对象 (3)利用构造函数创建对象

  6. Java中创建对象的5种方式 -[转] http://www.codeceo.com/article/5-ways-java-create-object.html...

    作为Java开发者,我们每天创建很多对象,但我们通常使用依赖管理系统,比如Spring去创建对象.然而这里有很多创建对象的方法,我们会在这篇文章中学到. Java中有5种创建对象的方式,下面给出它们的 ...

  7. java method 创建_java中创建对象的5种方式

    作为Java开发者,我们每天创建很多对象,但我们通常使用依赖管理系统,比如Spring去创建对象.然而这里有很多创建对象的方法. Java中有5种创建对象的方法,下面列出例子还有他们的字节码: 使用n ...

  8. Java中创建对象的5种方式

    转载 https://www.cnblogs.com/wxd0108/p/5685817.html 作为Java开发者,我们每天创建很多对象,但我们通常使用依赖管理系统,比如Spring去创建对象.然 ...

  9. java中创建对象的方式有哪些,Java中创建对象的四种方式

    四种方式: http://wenku.baidu.com/link?url=mv6VbMd3d-aCkbGMhn6rbLwFbef7v60nRbyA-thP6Y7hqtjiv0K0_kdtfOWaUj ...

最新文章

  1. java高级特性2,Java高级特性 2
  2. python爬取慕课视频-Python爬虫抓取技术的门道
  3. 吹爆了这个可视化神器,上手后直接开大~
  4. 【已解决】Unable to resolve column ‘name‘
  5. 大三了,计算机专业学生的困惑。 [转]
  6. Golang的cookie
  7. 离人计算机乐谱,离人简谱 林志炫离人挥霍着眼泪,回避还在眼前的离别
  8. 技术交流|网络安全设备为什么要用Bypass功能
  9. WAP1 X/WAP2 0以及WAP浏览器的协议版本
  10. Android MeasureSpec理解
  11. 有关人工智能方面的调研报告
  12. windows命令提示符
  13. S3C2440c语言汇编传参点灯
  14. Docker Windows Containers
  15. 基于Arduino的温湿度上传OneNET,同时SIM900A短信报警(1)
  16. Bochs源码分析 - 16:conforming与non-conforming代码段区别以及Bochs代码的实现
  17. zabbix触发器通过钉钉发送警报
  18. ps怎么抠图?教你怎么用钢笔工具抠图
  19. Python开发转盘小游戏
  20. 沉肩、坠肘、塌腰,学这一个动作就都做到了

热门文章

  1. Ubuntu 9.04安设教程(傻瓜版)
  2. Android Bundle类 学习总结
  3. 20行以内python代码画出各种减压图
  4. [Xcode 实际操作]七、文件与数据-(2)创建文件夹
  5. CF385C Bear and Prime Numbers
  6. 洛谷P1730最小密度路径
  7. 自写网站阶段之:终结篇
  8. 收集的不错的计算机图书
  9. android 资源引用 自定义标题栏
  10. 数据库LINQ TO SQL在Silverlight中的应用(WCF)------学习笔记(一)