阅读本文约需要6分钟

大家好,我是你们的导师,我每天都会在这里给大家分享一些干货内容(当然了,周末也要允许老师休息一下哈)。上次老师跟大家分享了JS 之类的知识,今天跟大家分享下JS 之创建对象的知识。

1 JS 之创建对象

参考文献:https://segmentfault.com/a/1190000016155973

本篇文章给大家介绍7种非常经典的JavaScript创建对象方式。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。JavaScript创建对象的方式有很多,通过Object构造函数或对象字面量的方式也可以创建单个对象,显然这两种方式会产生大量的重复代码,并不适合量产。接下来介绍七种非常经典的创建对象的方式,他们也各有优缺点。(内容主要来自于《JavaScript高级程序设计》,还参考了一下别人写的文章。

一、工厂模式

function createPerson(name, job) { var o = new Object(); o.name = name; o.job = job; o.sayName = function() {  console.log(this.name); } return o}var person1 = createPerson('Mike', 'student')var person2 = createPerson('X', 'engineer')

可以无数次调用这个工厂函数,每次都会返回一个包含两个属性和一个方法的对象。工厂模式虽然解决了创建多个相似对象的问题,但是没有解决对象识别问题,即不能知道一个对象的类型。

二、构造函数模式

function Person(name, job) { this.name = name; this.job = job; this.sayName = function() {  console.log(this.name); }}var person1 = new Person('Mike', 'student')var person2 = new Person('X', 'engineer')

没有显示的创建对象,使用new来调用这个构造函数,使用new后会自动执行如下操作:①创建一个新对象;②将构造函数的作用域赋给新对象(因此this就指向了这个新对象);③执行构造函数中的代码(为这个新对象添加属性);④返回新对象。缺点:每个方法都要在每个实例上重新创建一遍。创建两个完成同样任务的的Function实例的确没有必要。况且有this对象在,根本不用在执行代码前就把函数绑定到特定的对象上,可以通过这样的形式定义:

function Person( name, age, job ){    this.name = name;    this.age = age;    this.job = job;    this.sayName = sayName;}function sayName(){    alert( this.name );}

如此一来,就可以将sayName()函数的定义转移到构造函数外部。而在构造函数内部,我们将sayName属性设置成全局的sayName函数。这样的话,由于sayName包含的是一个指向函数的指针,因此person1和person2对象就可以共享在全局作用域中定义的同一个sayName()函数。这样做解决了两个函数做同一件事的问题,但是新的问题又来了:在全局作用域中定义的函数实际上只能被某个对象调用,这让全局作用域有点名不副实。而更重要的是:如果对象需要定义很多方法,那么就需要定义很多个全局函数,这样一来,我们自定义的这个引用类型就毫无封装性可言了。这些问题可以通过使用原型模式来解决。

三、原型模式

function Person() {}Person.prototype.name = 'Mike'Person.prototype.job = 'student'Person.prototype.sayName = function() { console.log(this.name)}var person1 = new Person()

将信息直接添加到原型对象上。使用原型的好处是可以让所有的实例对象共享它所包含的属性和方法,不必在构造函数中定义对象实例信息,而是可以将这些信息直接添加到原型对象中。①理解原型无论什么时候,只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性。在默认情况下,所有prototype属性都会自动获得一个constructor(构造函数)属性,这个属性包含一个指向prototype属性所在函数的指针。每当代码读取某个对象的某个属性时,都会执行一搜索,目标是具有给定名字的属性。搜索首先从对象实例本身开始。如果在实例中找到了具有给定名字的属性,则返回该属性的值;如果没有找到,则继续搜索指针指向的原型对象,在原型对象中查找具有给定名字的属性。如果在原型对象中找到了这个属性,则返回该属性的值。虽然可以通过对象实例访问保存在原型中的值,但却不能通过对象实例重写原型中的值。如果我们在实例中添加了一个属性,而该属性与实例中的一个属性同名,那么就会在实例中创建该属性,该属性将会屏蔽原型中的那个属性。即使是将属性设置为null,也只是在实例中的属性值为null。不过,使用delete操作符可以完全删除实例属性,从而能够重新访问原型中的属性。使用hasOwnProperty() 方法可以检测一个属性是存在于实例中,还是存在与原型中。这个方法只在给定属性存在于对象实例中时,才会返回true。②原型与in操作符in操作符会在通过对象能够访问给定属性时返回true,无论该属性是存在于实例中还是原型中。③更简单的原型语法

function Person(){}Person.prototype = {    name : "Mike",    age : 29,    job : "engineer",    syaName : function(){        alert( this.name );    }};

在上面的代码中,将Person.prototype设置为等于一个以对象字面量形式创建的新对象。最终结果相同,但有一个例外:constructor属性不再指向Person。

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

组合使用构造函数模式和原型模式是使用最为广泛、认同度最高的一种创建自定义类型的方法。它可以解决上面那些模式的缺点,使用此模式可以让每个实例都会有自己的一份实例属性副本,但同时又共享着对方法的引用,这样的话,即使实例属性修改引用类型的值,也不会影响其他实例的属性值了。还支持向构造函数传递参数,可谓是集两种模式的优点。

function Person(name) { this.name = name; this.friends = ['Jack', 'Merry'];}Person.prototype.sayName = function() { console.log(this.name);}var person1 = new Person();var person2 = new Person();person1.friends.push('Van');console.log(person1.friends) //["Jack", "Merry", "Van"]console.log(person2.friends) // ["Jack", "Merry"]console.log(person1.friends === person2.friends) //false

五、动态原型模式

动态原型模式将所有信息都封装在了构造函数中,初始化的时候。可以通过检测某个应该存在的方法是否有效,来决定是否需要初始化原型。

function Person(name, job) {  // 属性 this.name = name; this.job = job; // 方法 if(typeof this.sayName !== 'function') {  Person.prototype.sayName = function() {    console.log(this.name)  } }}var person1 = new Person('Mike', 'Student')person1.sayName()

只有在sayName方法不存在的时候,才会将它添加到原型中。这段代码只会初次调用构造函数的时候才会执行。此后原型已经完成初始化,不需要在做什么修改了,这里对原型所做的修改,能够立即在所有实例中得到反映。其次,if语句检查的可以是初始化之后应该存在的任何属性或方法,所以不必用一大堆的if语句检查每一个属性和方法,只要检查一个就行。

六、寄生构造函数模式

这种模式的基本思想就是创建一个函数,该函数的作用仅仅是封装创建对象的代码,然后再返回新建的对象

function Person(name, job) {  var o = new Object(); o.name = name; o.job = job; o.sayName = function() {  console.log(this.name) } return o}var person1 = new Person('Mike', 'student')person1.sayName()

这个模式,除了使用new操作符并把使用的包装函数叫做构造函数之外,和工厂模式几乎一样。构造函数如果不返回对象,默认也会返回一个新的对象,通过在构造函数的末尾添加一个return语句,可以重写调用构造函数时返回的值。

七、稳妥构造函数模式

首先明白稳妥对象指的是没有公共属性,而且其方法也不引用this。稳妥对象最适合在一些安全环境中(这些环境会禁止使用this和new),或防止数据被其他应用程序改动时使用。稳妥构造函数模式和寄生模式类似,有两点不同:1.是创建对象的实例方法不引用this;2.不使用new操作符调用构造函数

function Person(name, job) { var o = new Object(); o.name = name; o.job = job; o.sayName = function() {  console.log(name) //注意这里没有了"this"; } return o}var person1 = Person('Mike', 'student')person1.sayName();

和寄生构造函数模式一样,这样创建出来的对象与构造函数之间没有什么关系,instanceof操作符对他们没有意义。今天就分享这么多,JS 之创建对象的知识点会了多少欢迎在留言区评论,对于有价值的留言,我们都会一一回复的。如果觉得文章对你有一丢丢帮助,请点右下角【在看】,让更多人看到该文章。

js 创建file对象_JS 之创建对象相关推荐

  1. js创建file对象 字符串 txt_js-创建对象的多种方式

    1. 工厂模式 function createPerson(name) { var o = new Object(); o.name = name; o.getName = function () { ...

  2. 动态js创建数组对象

    动态js创建数组对象 var items = []; for (var i = 0; i < 10; i++) { items.push({ id: i, level: i + '级' }) }

  3. JS 创建自定义对象的方法

    工厂模式 优点:接受参数,可以无数次的调用这个函数,创建Person对象,而每次他都可以返回一个包含三个属性一个方法的对象. 缺点:虽然解决了创建多个相似对象的问题,但是没有解决对象识别的问题(即怎么 ...

  4. IO流基础,创建File对象与方法是用

    1.io流主要用途读取本地文件或服务器文件,进行本地或者服务器开呗工作 构造函数    绝对路径够构造方法:    File f = new File("D:\\test\\a.txt&qu ...

  5. 用js创建audio对象实现网页迷你音乐播放器

    主要是靠咋没的audio对象,我就不多说废话了,也不会说,直接上代码: HTML <!DOCTYPE html> <html><head><meta http ...

  6. [JS] 聊一聊File对象

    File 是一个构造函数 是一种特殊的Blob const fooFile = new File(['foo'], 'foo.txt', {type: ''text/plain})  // 得到一个内 ...

  7. 微信小程序 js创建Object对象

    参考链接: (1)微信小程序开发教程之Object对象 https://www.hishop.com.cn/xiaocx/show_36804.html 一.创建对象 (1)通过函数的形式来创建对象( ...

  8. js 操作java对象_js对象复制

    转至:http://apps.hi.baidu.com/share/detail/518475 在js里没有类似JAVA的clone方法,无法实现对对象的克隆,一般使用等号操作符来传递对象,但这样就造 ...

  9. js向服务器写入文件,js创建、写入、读取文件、FileSystemObject

    FileSystemObject FileSystemObject是IIS 内置组件,用于访问服务器上的文件系统(比如操作磁盘.文件夹或文本文件).FSO 不能操作二进制文件,要操作二进制文件,使用: ...

最新文章

  1. Android百度地图开发 百度地图得到当前位置
  2. php python-浅谈php调用python文件
  3. 下列哪个不是目前python里的内置模块-python的内置模块math在哪个文件里
  4. 06.Spring 资源加载 - ResourceLoader
  5. codis 部署和测试
  6. 钮扣电池电压电量_纽扣厂
  7. 手把手教你用Python读取Excel
  8. java redis tokenid_基于Spring及Redis的Token鉴权
  9. MyCat双机HA高可用集群搭建_HAProxy安装和配置---MyCat分布式数据库集群架构工作笔记0028
  10. Python实现鸢尾花数据集分类问题——基于skearn的LogisticRegression
  11. 子程序入口参数是什么_三菱FX PLC | 什么是中断服务?没事多看几遍
  12. jQuery判断Dom对象是否存在
  13. python数据分析之(4)读写数据文件CSV,EXCEL等
  14. 2018美赛B题总结
  15. xss.haozi.me解题记录
  16. 图神经网络(GNN)资源帖视频及必读论文
  17. 《.NET大局观》--嬗变的痛苦
  18. 2014校园招聘笔、面经历总结---华为双选会
  19. hammer.js教程2
  20. C# EF框架(一)配置

热门文章

  1. STM32工作笔记045---SystemInit时钟系统初始化函数剖析
  2. VB.NET工作笔记003---使用ASP_vbs脚本_或vb.net调用Sqlserver DTS文件
  3. Linux工作笔记032---Centos7.3/8.2 下安装mysql_不局限于MySql版本
  4. Android学习笔记---29_构建soap协议内容,发送xml数据和调用webservice,手机号码归属地查询器
  5. python数据结构剑指offer-两个链表的第一个公共结点
  6. opencv编译问题
  7. MFC中从一个类向其他类发送消息的方法
  8. ftk学习记(消息框篇)
  9. c语言直流电机控制实验报告,直流电机实验报告.docx
  10. 串行异步通信_每天学一点/ 电工:PLC:串行通信