工厂模式

工厂模式非常直观,将创建对象的过程抽象为一个函数,用函数封装以特定接口创建对象的细节。如下所示:

function createStudent(name,sex,grade){                                                         var o = new Object();o.name = name;o.sex = sex;o.grade = grade;o.sayName = function(){console.log(this.name);}return o;
}
var s1 = createStudent('Claiyre','famale',1);复制代码

通俗地讲,工厂模式就是将创建对象的语句放在一个函数里,通过传入参数来创建特定对象,最后返回创建的对象。

工厂模式虽然可以创建多个相似的对象,但却不能解决对象标识的问题,即怎样知道一个对象的类型。构造函数模式应运而生。

构造函数模式

构造函数模式是java语言创建对象的通用方式。两种语言用构造函数创建对象的方式略有不同,注意区别。
在JavaScript中没有类的概念,函数即为一等公民,因此,不必显式声明某个类,直接创建构造函数即可,类的方法和属性在构造函数中(或原型对象上)处理。构造函数模式的示例代码如下:

function Student(name,sex,grade){                                                   this.name = name;this.sex = sex;this.grade = grade;this.sayName = function(){console.log(this.name);}
}
var s2 = new Student('孙悟空','male',2);复制代码

细心的朋友一定发现了构造函数的函数名首字母是大写的,而普通函数首字母则是小写,这是众多OO语言约定俗成的规定,虽然大多数情况下不大写也不会报错,但是为了代码的规范性和可读性,还是应该将构造函数的首字母大写,与普通函数区别开。
与工厂模式相比,用构造模式创建对象有以下几点不同:

  • 没有显示地创建对象
  • 直接将属性和方法赋给this对象
  • 没有return语句

此外,还应注意到要创建Student的实例,必须要使用new操作符,创建的实例对象将有一个constructor(构造器)属性,指向Person构造函数。调用构造函数创建对象经过了以下几个过程:

  • 创建一个新对象
  • 将构造函数的作用域赋给新对象(因此this就指向了这个新对象)
  • 执行构造函数中的代码
  • 返回新对象(不需要显式返回)

构造函数虽好用,但也不是没有缺点。使用构造函数的主要问题是:每个方法都要在每个实例上创建一遍。在ECMAScript中,函数即对象,因此每定义一个函数,也就是实例化了一个对象。下面的例子证明了这个缺点。

var s3 = new Student('唐僧','male',3);
var s4 = new Student('白骨精','female',4);
s3.sayName();
s4.sayName();
console.log(s3.sayName == s4.sayName);复制代码

运行结果:

也就是说通过构造函数实例化的多个对象的方法,是多个不同的方法,但它们内部的代码以及实现的功能是相同的,这就造成了一定的资源浪费。
幸运的是,这个问题可以用原型模式来解决。

原型模式

js中,每个函数都有一个prototype属性,它是一个指针,指向一个对象,叫做原型对象,原型对象包含了可以由特定类型的所有实例对象共享的属性和方法。此外,这个对象有一个与生自来的属性constructor,指向创建对象的构造方法。
使用原型模式可以让所有的实例共享原型对象中的属性和方法,也就是说,不必再构造函数中定义对象实例的信息。用代码表示如下:

function Student_1(){}
Student_1.prototype.name = 'Claiyre';
Student_1.prototype.sex = 'female';
Student_1.prototype.class = 5;
Student_1.prototype.sayName = function (){console.log(this.name);
}var s5 = new Student_1();
s5.sayName();    //Claiyre
var s6 = new Student_1();
s6.sayName();    //Claiyre复制代码

一张图胜过千言万语,下图清楚地阐释了各个对象和原型对象间的关系:

了解过原型后,可以继续在实例对象上增添属性或方法:

s6.name = 'John';
s6.sayName();       //John复制代码

当要读取某个对象的属性时,都会执行一次搜索,搜索首先从对象实例本身开始,如果在实例中找到了这个属性,则搜索结束,返回实例属性的值;若实例上没有找到,则继续向对象的原型对象延伸,搜索对象的原型对象,若在原型对象上找到了,则返回原型上相应属性的值,若没有找到,则返回undefined。因此,实例对象属性会覆盖原型对象上的同名属性,所以上面第二行代码输出的是John。

  • Object.getPrototypeOf(object)方法返回参数对象的原型对象。
  • Object.keys(object)方法返回对象上课枚举的实例属性。

原型中的所有属性都是被所有实例所共享的,这种共享对于函数来说非常合适,对于包含基本值的属性也说的过去(实例属性会覆盖原型同名属性),但对于那些包含引用类型的属性,可有大麻烦了

Student_1.prototype.friends = ['aa','bb'];console.log('s6的朋友' + s6.friends);
s5.friends.push('cc');
console.log('s5的朋友' + s5.friends);
console.log('s6的朋友' + s6.friends);复制代码

运行结果:

问题来了,我们只想改变s5的朋友列表,但由于原型模式的共享本质,s6的朋友列表也随之改变了。
因此,很少单独使用原型模式。

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

构造函数模式用于定义实例属性,原型模式则用于定义方法和共享的属性。这种混合模式不仅支持向构造函数传入参数,还最大限度地节约了内存,可谓是集两模式之长。示例代码如下:

function Student(name,sex,grade){                                                   this.name = name;this.sex = sex;this.grade = grade;
}Student.prototype.sayName = function(){console.log(this.name);
}
Student.prototype.school = 'Joooh school';复制代码

其他模式

除了以上几种常见的模式外,批量创建对象的方式还有

  • 动态原型模式:仅在第一次调用构造函数时,将方法赋给原型对象的相应属性,其他示例的处理方式同构造函数模式
  • 寄生构造函数模式:仅仅封装创建对象的代码,然后再返回新创建的对象,仍使用new操作符调用
  • 稳妥构造函数模式:没有公共属性,只有私有变量和方法,以及一些get/set方法,用以处理私有变量。

转载于:https://juejin.im/post/5cdd10dee51d456e5c5babdd

js创建对象的几种方法相关推荐

  1. JS创建对象的三种方法

    在JavaScript中,对象是一组无序的相关属性和方法的集合.所有的实物都是对象,例如,字符串.数值.数组.函数等. 下面我会介绍三种创建对象的方法. 一.通过字面量创建对象 其语法格式如下: va ...

  2. JS创建对象模式7种方法详解

    创建对象的几种模式 虽然Object构造函数或者字面量,都可以用来创建对象,但这些方式有明显的缺点:使用同一个接口创建很多对象,会产生大量的代码, 于是,工厂模式诞生了 1 工厂模式 工厂模式是广为人 ...

  3. js创建对象的几种方法及继承

    创建对象 通过Object构造函数或对象字面量创建单个对象  这些方式有明显的缺点:使用同一个接口创建很多对象,会产生大量的重复代码.为了解决这个问题,出现了工厂模式.   工厂模式    考虑在ES ...

  4. js创建对象的四种方法

    1.利用new Object()创建对象 2. 字面量创建对象 3.工厂模式创建对象 4. 利用构造函数创建对象 <script>//利用new Object()创建对象var obj1 ...

  5. 动态加载JS脚本的4种方法

    动态加载JS脚本的4种方法 2006-12-04 15:33 要实现动态加载JS脚本有4种方法: 1.直接document.write <script language="javasc ...

  6. JavaSE(二十五)——String与StringBuffer、StringBuilder的区别、创建对象的几种方法、Http和Https的区别

    文章目录 1. String与StringBuffer.StringBuilder的区别 2. Java创建对象的几种方法 3. Http和Https的区别 1. String与StringBuffe ...

  7. node.js取参四种方法req.body,req.params,req.param,req.body

    node.js取参四种方法req.body,req.params,req.param,req.body 参考:https://my.oschina.net/u/2519530/blog/535309 ...

  8. JavaScript创建对象的4种方法

    JavaScript 创建对象的4种方法 所谓对象就是用来帮助你完成一些事情是,对象是有特征和行为的,是具体特指的某一个事物.使用对象可以使程序更加整洁 通过Object()方法来创建 Object( ...

  9. js延迟加载的几种方法

    这是一个面试经常问到的问题:js的延迟加载方法 (js的延迟加载有助与提高页面的加载速度) 主要考察对程序的性能方面是否有研究,程序的性能是一个项目不断地追求的,通常也是项目完成后需要长期做的一件事情 ...

最新文章

  1. 中间件业务在网易轻舟容器平台的性能调优实践
  2. 高级停靠(Dock)技术的实现
  3. 傅里叶变换的初级理解一
  4. 科大星云诗社动态20210217
  5. java数组有顺序吗_java – 使用特定顺序对(数组)列表进行排序
  6. python返回菜单_返回上一菜单
  7. JDBC和servlet设计思路、DAO模式思路、MVC思路粗略总结
  8. 【To Understand !!! DP or 递归】LeetCode 87. Scramble String
  9. Q96:PT(3.2):包裹的基于噪声的纹理(Wrapped Noise-Based Textures)
  10. Spark Row对象入门到熟悉
  11. 分表分页/跨库分页为什么这么难?
  12. Atitit. 有限状态机 fsm 状态模式
  13. Linux - Vim常用命令清单
  14. 平衡自行车的原理以及制作方法
  15. mysql特性绕过安全狗_【经验总结】SQL注入Bypass安全狗360主机卫士
  16. 用Asp.net 就能轻松实现铁道部的订票系统
  17. 梅捷512G固态拆机+得一微YS9082HP量产教程+YS9082HP开卡工具
  18. 小米手机第三方卡刷软件_小米Max卡刷教程_小米Max用recovery刷第三方系统包
  19. python 根据word生成ppt_未明学院:利用Python将Wordamp;PPT批量转成PDF
  20. 玩转iOS开发:iOS 10 新特性《Siri Kit Intents Extension UI》

热门文章

  1. java.sql.SQLException: java.lang.StackOverflowError
  2. 摩根上调 思科股票评级至增持
  3. 祝51CTO 生日快乐
  4. linux 后台进程
  5. 各种flash的不同
  6. sar分辨率公式_初识合成孔径雷达SAR
  7. python求无序列表中位数_python 实现在无序数组中找到中位数方法
  8. netbeans 添加gif图片_怎么制作动态图片?手机如何制作清晰gif动图?
  9. 激光打标软件_走向工业自动化生产之路——激光飞行打标
  10. JSP 异常处理如何处理?