位置: 编程技术 - 正文

在javascript中创建对象的各种模式解析(javascript create)

编辑:rootadmin

推荐整理分享在javascript中创建对象的各种模式解析(javascript create),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:创建javascript函数,如何在javascript中创建对象,在javascript中创建自定义函数进行两个整数的交换,如何在javascript中创建对象,在javascript中创建数组方法有哪些,创建javascript函数,在javascript中创建自定义函数进行两个整数的交换,在javascript中创建数组方法有哪些,内容如对您有帮助,希望把文章链接给更多的朋友!

最近在看《javascript高级程序设计》(第二版)

javascript中对象的创建

&#;工厂模式

&#;构造函数模式

&#;原型模式

&#;结合构造函数和原型模式

&#;原型动态模式

面向对象的语言大都有一个类的概念,通过类可以创建多个具有相同方法和属性的对象。虽然从技术上讲,javascript是一门面向对象的语言,但是javascript没有类的概念,一切都是对象。任意一个对象都是某种引用类型的实例,都是通过已有的引用类型创建;引用类型可以是原生的,也可以是自定义的。原生的引用类型有:Object、Array、Data、RegExp、Function。 !引用类型就是一种数据结构,将数据和功能组织在一起,通常被称为类。 缺乏类概念的javascript中,需要解决的问题就是如何高效的创建对象。

1.1.0.创建对象的一般方法

基于Object引用类型,创建了一个对象,该对象包含四个属性,其中一个为方法。如果需要很多类似person的实例,那就会有许多重复的代码。

1.1.1.工厂模式

通过一个可以包含了对象细节的函数来创建对象,然后返回这个对象。

每次调用person函数,都会通过该函数内部的对象o创建新的对象,然后返回,除此之外,这个为了创建新对象而存在的内部对象o没有其他的用途。另外,无法判断工厂模式创建的对象的类型。

1.1.2.构造函数模式

对比工厂模式,可以发现,这里并不需要创建中间对象,没有return。另外,可以将构造函数的实例标识为一种特定的类型,这就解决了对象识别的问题(通过检查实例的constructor属性,或利用instanceof操作符检查该实例是否通过某个构造函数创建)。

console.log(person1.constructor == Person);//constructor位于构造函数原型中,并指向构造函数,结果为true

console.log(person1 instanceof Person);//通过instanceof操作符,判断person1是否为构造函数Person的实例但构造函数模式也有自己的问题,实际上,logName方法在每个实例上都会被重新创建一次,需要注意的是,通过实例化创建的方法且并不相等,以下代码将会得到false:

console.log(person1.logName == person2.logName);//false我们可以将方法移到构造器外部(变为全局函数)来解决这个问题:

但是,在全局下创建的全局函数实际上只能被经由Person创建的实例调用,这就有点名不副实了;如果方法很多,还需要逐一定义,缺少封装性。

1.1.3.原型模式

javascript中的每一个函数都包含一个指向prototype属性的指针(大部分浏览器可以通过内部属性__proto__访问),prototype属性是一个对象,其中包含了由某种引用类型创建的所有实例共享的属性和方法。

以上代码做了这几件事情:

1.定义了一个构造函数Person,Person函数自动获得一个prototype属性,该属性默认只包含一个指向Person的constructor属性;

2.通过Person.prototype添加三个属性,其中一个作为方法;

在javascript中创建对象的各种模式解析(javascript create)

3.创建一个Person的实例,随后在实例上调用了logName()方法。 !

这里需要注意的是logName()方法的调用过程:

1.在person1实例上查找logName()方法,发现没有这个方法,于是追溯到person1的原型

2.在person1的原型上查找logame()方法,有这个方法,于是调用该方法 基于这样一个查找过程,我们可以通过在实例上定义原型中的同名属性,来阻止该实例访问原型上的同名属性,需要注意的是,这样做并不会删除原型上的同名属性,仅仅是阻止实例访问。

var person2 = new Person();

person2.name = 'laocai';如果我们不再需要实例上的属性时,可以通过delete操作符删除。

delete person2.name;利用for-in循环枚举出实例可以访问到的所有属性(不论该属性存在于实例或是原型中):

同时,也可以利用hasOwnProperty()方法判断某个属性到底存在于实例上,还是存在于原型中,只有当属性存在于实例中,才会返回true:

console.log(person1.hasOwnProperty('name'));//true!hasOwnProperty来自Object的原型,是javascript中唯一一个在处理属性时不查找原型链的方法。[via javascript秘密花园] 另外,也可以通过同时使用in操作符和hasOwnProperty()方法来判断某个属性存在于实例中还是存在于原型中:

console.log(('friends' in person1) && !person1.hasOwnProperty('friends'));先判断person1是否可以访问到friends属性,如果可以,再判断这个属性是否存在于实例当中(注意前面的!),如果不存在于实例中,就说明这个属性存在于原型中。 前面提到,原型也是对象,所以我们可以用对象字面量表示法书写原型,之前为原型添加代码的写法可以修改为:

由于对象字面量语法重写了整个prototype原型,原先创建构造函数时默认取得的constructor属性会指向Object构造函数:

//对象字面量重写原型之后console.log(person1.constructor);//Object不过,instanceof操作符仍会返回希望的结果:

//对象字面量重写原型之后console.log(person1 instanceof Person);//true当然,可以在原型中手动设置constructor的值来解决这个问题。

如果在创建对象实例之后修改原型对象,那么对原型的修改会立即在所有对象实例中反映出来:

实例和原型之间的连接仅仅是一个指针,而不是一个原型的拷贝,在原型实际上是一次搜索过程,对原型对象的所做的任何修改都会在所有对象实例中反映出来,就算在创建实例之后修改原型,也是如此。 如果在创建对象实例之后重写原型对象,情况又会如何?

以上代码在执行到最后一行时会出现未定义错误,如果我们用for-in循环枚举person1中的可访问属性时,会发现,里头空无一物,但是person2却可以访问到原型上的friends属性。 !重写原型切断了现有原型与之前创建的所有对象实例的联系,之前创建的对象实例的原型还在,只不过是旧的。

需要注意的是,原型模式忽略了为构造函数传递参数的过程,所有的实例都取得相同的属性值。同时,原型模式还存在着一个很大的问题,就是原型对象中的引用类型值会被所有实例共享,对引用类型值的修改,也会反映到所有对象实例当中。

修改person1的引用类型值friends,意味着person2中的friends也会发生变化,实际上,原型中保存的friends实际上只是一个指向堆中friends值的指针(这个指针的长度是固定的,保存在栈中),实例通过原型访问引用类型值时,也是按指针访问,而不是访问各自实例上的副本(这样的副本并不存在)。

1.1.4.结合构造函数和原型模式创建对象

结合构造函数和原型模式的优点,弥补各自的不足,利用构造函数传递初始化参数,在其中定义实例属性,利用原型定义公用方法和公共属性,该模式应用最为广泛。

1.1.5.原型动态模式

原型动态模式将需要的所有信息都封装到构造函数中,通过if语句判断原型中的某个属性是否存在,若不存在(在第一次调用这个构造函数的时候),执行if语句内部的原型初始化代码。

需要注意的是,该模式不能使用对象字面量语法书写原型对象(这样会重写原型对象)。若重写原型,那么通过构造函数创建的第一实例可以访问的原型对象不会包含if语句中的原型对象属性。

需要说明的是,各模式都有自己的应用场景,无所谓优劣。

以上这篇在javascript中创建对象的各种模式解析就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持积木网。

详解JavaScript设计模式开发中的桥接模式使用 桥接模式将抽象部分与实现部分分离开来,使两者都可以独立的变化,并且可以一起和谐地工作。抽象部分和实现部分都可以独立的变化而不会互相影

设计模式中的组合模式在JavaScript程序构建中的使用 定义组合,顾名思义是指用包含多个部件的对象创建单一实体。这个单一实体将用作所有这些部件的访问点,虽然这大大简化了操作,但也可能具有相

JavaScript设计模式开发中组合模式的使用教程 我们平时开发过程中,一定会遇到这种情况:同时处理简单对象和由简单对象组成的复杂对象,这些简单对象和复杂对象会组合成树形结构,在客户端

标签: javascript create

本文链接地址:https://www.jiuchutong.com/biancheng/370043.html 转载请保留说明!

上一篇:浅析js绑定事件的常用方法(js的事件绑定)

下一篇:详解JavaScript设计模式开发中的桥接模式使用(javascript怎么设置)

  • 个人独资企业要注意什么
  • 出口退税申报系统安装路径
  • 500以下的收据可以入账吗
  • 个税申报初始化密码
  • 收到电子退库的摘要怎么写
  • 劳动法相关法规
  • 已经退款买家不退货怎么办
  • 预缴税款缴多了怎么办
  • 如何降低应用耗电
  • 企业增加注册资金怎么办理
  • 新公司做财务
  • 长期待摊费用可以抵扣吗
  • 出差补助没有发票计入什么科目
  • 公司换法人公司账户怎么办
  • 增值税研发和技术服务内容
  • 建筑行业预收账款
  • 土地增值税计算题及答案解析
  • 个体户要申报
  • 直接快递到国外的货物如何收汇?
  • 旅行社开的发票是否都要差额征税
  • 办公室空调维修属于办公费吗
  • 驾校如何用完工百分比法确认收入?
  • w11系统激活码
  • 苹果手机移动到新手机
  • 计提工资大于实际工资
  • 公司和个人分别交税一部分吗
  • 工会举办比赛,参赛人员差旅费可以在工会报销吗
  • 预计资产未来现金流量的期限
  • backup是什么文件夹怎么能打开
  • 电脑自动安装乱七八糟的软件win7
  • 我整理的邪恶铭刻所有卡牌及自制卡
  • nginx静态文件服务器
  • 企业工商年检什么意思
  • php redis数据类型
  • java定时器怎么用
  • web前端期末大作业旅游页面
  • 检测费可以抵扣增值税吗
  • 金融企业贷款损失税前扣除
  • springmvc的执行流程
  • 账面未分配利润等于净利润?
  • 期货收入交个人所得税吗
  • 前端日报
  • 怎样进行制造费用的归集
  • 成立一般纳税人公司流程
  • 解决掉发的有效方法
  • 一次性计入当期成本费用是什么意思
  • sql 临时数据
  • 享受残疾人增值服务的是
  • 一般纳税人认定标准
  • 以前年度损益调整科目编码是多少
  • 银行承兑汇票如何签收
  • 以前年度多计提成本怎么处理
  • 支付给个人的佣金如何代扣个税
  • 出口退税的范围是多少
  • 销售过程中发生的商业折扣计入
  • 交易性金融资产入账价值怎么计算
  • 筹建期业务招待费的扣除标准
  • 会计做账手工帐
  • Linux下安装mysql-5.6.12-linux-glibc2.5-x86_64.tar.gz
  • mysql的密码忘了该怎么办
  • linux防火墙设置firewalld
  • 360tray占用大量内存
  • windows10出现飞行模式怎么办
  • LiteSpeed添加虚拟主机+支持htaccess图文教程
  • win10系统下怎么将腾讯qlv格式转换mp4格式?
  • unity锚点
  • opengl导入obj
  • cocos2djs
  • opengl learn cn
  • 使用vue-cli快速搭建vue项目
  • 批处理在windows中的典型应用
  • js 浏览器全屏
  • Node.js node-schedule定时任务隔多少分钟执行一次的方法
  • python语言解析
  • 营改增之前建筑业税率是多少
  • 高速公路过路费一公里多少钱
  • 云南省地方税务局公告2017年第2号
  • 成都个税证明
  • 改革概念股是什么
  • 华数tv业务认证账号
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设