JavaScript之面向对象学习六原型模式创建对象的问题,组合使用构造函数模式和原型模式创建对象
一、仔细分析前面的原型模式创建对象的方法,发现原型模式创建对象,也存在一些问题,如下:
1、它省略了为构造函数传递初始化参数这个环节,结果所有实例在默认的情况下都将取得相同的属性值,这还不是最大的问题!
2、最大的问题是原型中的所有属性是被很多实例所共享的,这种共享对于函数非常合适,对于那些包含基本值的属性也说得过去,因为我们知道可以在实例上添加一个同名属性,可以隐藏原型中的对应属性。但是对于包含应用类型值的属性来说,问题就非常严重了,代码如下:
function Person(){
}
Person.prototype={
constructor:Person,
name:"张三",
age:22,
job:"coder",
friends:["李四","王五"],
sayName:function(){
alert(this.name);
}
}
var person1=new Person();
var person2=new Person();
person1.friends.push("赵六");
alert(person1.friends); //输出:李四,王五,赵六
alert(person2.friends);//输出:李四,王五,赵六
分析上面的代码,当我们为person1添加一个朋友的时候,发现person2同时也被添加了一个朋友,但这并不是我们想要的,而这正是因为原型模式的共享的本性所导致的,只要任何一个实例修改了原型属性对象中的属性值,所有与该原型对象关联的实例都会受到影响!
二、组合使用构造函数模式和原型模式
为了解决原型模式不能初始化参数和共享对于引用模式所存在的问题!这里我们可以采用构造函数模式和原型模式的结合模式来创建自定义类型,构造函数用于与解决初始化参数(实例属性的定义),原型模式用于共享 方法和constructor。
这种构造函数与原型组合的模式创建自定义类型,是ECMAScript中使用最广泛、认同度最高的一种创建自定义类型的方法。可以说,这是用来定义引用类型的一种默认模式。
代码如下:
function Person(name,age,job){
this.name=name;
this.age=age;
this.job=job;
this.friends=["小超","大超"];
}
Person.prototype={
constructor:Person,
sayName:function(){
alert(this.name);
}
}
var person1=new Person("张三",22,"coder");
var person2=new Person("李四",22,"coder");
person1.friends.push("Stephen Curry","Kevin Durant");
alert(person1.friends); //输出:小超,大超,Stephen Curry,Kevin Durant
alert(person2.friends);//输出:小超,大超
通过上面的输出我们发现组合使用构造函数模式和原型模式创建的自定义类型及解决了
1、构造函数:构造函数创建类型相同的函数,确是不同的作用域链和标识符解析(因为在JS中每创建一个函数就是一个对象,所以 (导致了构造函数中的方法) 在不同的实例中都需要重新创建一遍,但是这些方法做的确实同一件事情);
2、原型模式:其不能初始化参数,以及它的共享性对与一些引用类型所造成的影响(比如数组);
JavaScript之面向对象学习六原型模式创建对象的问题,组合使用构造函数模式和原型模式创建对象的更多相关文章
- JavaScript之面向对象学习七(动态原型模式、寄生构造函数模式、稳妥构造函数模式创建自定义类型)
一.动态原型模式 在面向对象学习六中的随笔中,了解到组合构造函数模式和原型模式创建的自定义类型可能最完善的!但是人无完人,代码亦是如此! 有其他oo语言经验的开发人员在看到独立的构造函数和原型时,很可 ...
- JavaScript之面向对象学习一
1.通过Object构造函数和对象字面量来创建对象缺点:使用同一个接口创建很多的对象,会产生大量的重复代码.比如我需要创建人的对象,并且需要三类人,医生.工程师.老师,他们可以抽象出很多属性,比如姓名 ...
- JavaScript之面向对象学习五(JS原生引用类型Array、Object、String等等)的原型对象介绍
1.原型模式的重要性不仅仅体现在创建自定义类型方面,就连所有的原生的引用类型(Obejct.Array.String等等)都在构造函数的原型上定义方法和属性.如下代码可以证明: alert(typeo ...
- JavaScript之面向对象学习八(继承)
简介:继承是OO语言中的一个最为人津津乐道的概念.许多OO语言都支持两种继承方式:接口继承和实现继承.接口继承只继承方法签名,而实现继承则继承实际的方法. 但是JS的函数并没有签名,所以在ECMASc ...
- JavaScript之面向对象学习四原型对象的动态性
1.由于在原型中查找值的过程是一次搜索,因此我们对原型对象所做的任何修改都能够立即从实例上反映出来---即便是先创建了实例后修改原型也是如此.代码如下: function Person(){ } va ...
- JavaScript之面向对象学习三原型语法升级
1.到目前为止,我们是时候分析下前面的使用原型语法来定义对象有哪些不足的地方,代码如下: function Person(){ } Person.prototype.name="张三&quo ...
- JavaScript之面向对象学习二(原型属性对象与in操作符)获取对象中所有属性的方法
1.原型属性对象于in操作符之in单独使用 有两种方式使用in操作符:单独使用和在for-in循环中使用.在单独使用中,代码如下: function Person(){ } Person.protot ...
- javascript创建对象的方法--组合模式
javascript创建对象的方法--组合模式 一.总结 0.作用:解决原型模式对象独有属性创建麻烦的问题 1.组合模式使用普遍:jquery就是用的组合模式,组合模式使用非常普遍 2.组合模式优点: ...
- javascript创建对象的方法--原型模式
javascript创建对象的方法--原型模式 一.总结 1.原型模式解决内存浪费的方法(继承):通过继承,对象继承原型模式下的所有属性,对象不同于其它对象的的属性自己创建或者修改 2.原型的使用(p ...
随机推荐
- Hessian Servlet和Hessian Spring的简单应用
转自: http://lancui.iteye.com/blog/935578 简介 相比WebService,Hessian更简单.快捷.采用的是二进制RPC协议(Binary),因为采用的是二进制 ...
- redis.conf配置详解
http://www.2cto.com/database/201307/225113.html
- OpenStreetMap(OSM) for developers
This article from: http://wiki.openstreetmap.org/wiki/Develop OpenStreetMap isn't just open data - i ...
- Linux学习之十三、快捷键与通配符、数据流重导向
通配符与特殊符号 接下来让我们利用通配符来玩些东西吧!首先,利用通配符配合 ls 找檔名看看: [root@www ~]# LANG=C <==由于与编码有关,先配置语 ...
- 关于oracle的certview
前两天去参加oracle 11g 的两门考试(1Z0-051和1Z0-052),在家看了好几遍题库,我本来想着上午一门,下午考一门,但是我嫌着麻烦,就预约一下午考完两门.在考试完一门后,发现成绩不 ...
- oralce DBA 培训_lesson06
控制文件 -小型二进制文件 -定义物理数据库的当前状态 -丢失控制文件须要修复 -维护数据库的完整性 -要求: 1.在启动数据库时处于mount状态 2.可以操作数据库 -仅仅链接至一个数据库 -最初 ...
- 自己主动更新--下载apk以及提示对话框的实现(3)
下载apk以及提示对话框的实现 一.步骤: 1. 确定有能够更新的版本号,对话框提醒用户是否进行更新. 2. 选择更新的话,显示下载对话框而且进行下载.否则关闭提示更新对话框. 3. Apk下载完毕后 ...
- 解决windows下Eclipse连接远程Hadoop报错
Exception in thread "main" java.lang.UnsatisfiedLinkError: org.apache.hadoop.io.nativeio.N ...
- Linux学习之修改主机名
1.临时修改主机名 显示主机名: oracle@localhost:~$ hostname localhost 修改主机名: oracle@localhost:~$ sudo hostname orc ...
- AutoCompleteTextview、MultiAutoCompleteTextView
AutoCompleteTextview 动态匹配输入内容文本框 属性: android:completionThreshold="2"; ...