Javascript面对对象. 第四篇
原型模式创建对象也有自己的缺点,它省略看构造函数传参初始化这一过程,带来的缺点就是初始化的值都是一致的。
而原型最大的缺点就是它优点,那就是共享。
原型中所有属性是被很多实例共享的,共享对于函数非常合适,对于包含基本值的属性也还可以,但如果属性包含引用类型。
就存在一定的问题:
function Box(){};
Box.prototype={
Constructor:Box,
name:"link",
age:25,
family:['哥哥','弟弟','妹妹'],
run:function(){
return this.name+this.age+'运行中。。。'
}
}
var box1=new Box();
alert(box1.family)
box1.family.push('姐姐') //添加一个引用类型
alert(box1.family) // 输出 哥哥弟弟妹妹姐姐
var box2=new Box();
alert(box2.family) //共享了box1添加的引用类型的原型 // 输出 哥哥弟弟妹妹姐姐
ps:数据共享的缘故,导致很多开发者放弃使用原型,因为每次实例化出的数据需要保留自己的特性,而不能共享。
为了解决构造传参和共享问题,可以组合构造函数+原型模式
function Box(name,age){ //不共享的使用构造函数
this.name=name;
this.age=age;
this.family=['哥哥','弟弟','妹妹'];
}
Box.prototype={ //共享的使用原型模式
constructor:Box,
run:function(){
return this.name+this.age+'运行中。。。'
}
}
var box1=new Box('link',25);
box1.family.push('姐姐')
alert(box1.run())
alert(box1.family) // 输出 哥哥弟弟妹妹姐姐
var box2=new Box('links',25);
alert(box2.run())
alert(box2.family) // 输出 哥哥弟弟妹妹
ps:这种混合模式很好的解决了传参和引用共享的大难题。是创建对象比较好的方法。
原型模式,不管你是否调用了原型中的共享方法,它都会初始化原型中的方法,并且在声明一个对象时,构造函数+原型部分很让人怪异,最好就是把构造函数和原型封装到一起。为了解决这个问题,我们可以使用动态原型模式。
//可以将原型封装到构造函数里面
function Box(name,age){
this.name=name;
this.age=age;
alert('初始化开始')
Box.prototype.run=function(){
return this.name+this.age+'运行中...'
}
alert('初始化结束')
}
//原型初始化,执行一次就行,没有必要每次都构造函数实例化的时候初始化!
var box1=new Box('link',53);
alert(box1.run()) var box2=new Box('that',5311);
alert(box2.run())
原型初始化,执行一次就行,没有必要每次都构造函数实例化的时候初始化!
function Box(name,age){
this.name=name;
this.age=age;
if(typeof this.run!='function'){ //查看this是否有run
alert('初始化开始')
Box.prototype.run=function(){
return this.name+this.age+'运行中...'
}
alert('初始化结束')
}
}
//原型初始化,执行一次就行!
var box1=new Box('link',53);
alert(box1.run())
var box2=new Box('that',5311);
alert(box2.run())
ps:使用动态原型模式,要注意一下,就是不可以再使用字面量的方式重写原型,因为会切断实例和新原型之间的关联。
如果这几种方式不能满足需求,可以使用一开始那种模式:寄生构造函数!
function Box(name,age){
var obj = new Object();
obj.name=name;
obj.age=age;
obj.run=function(){
return this.name+this.age+"运行中....."
}
return obj
}
var box1=new Box('link',53);
alert(box1.run())
ps:寄生构造函数,其实就是工厂模式+构造函数模式。这种模式比较通用,但是不能确定对象关系,所有,在可以使用之前所说的模式时,不建议使用此模式!
在什么情况下使用寄生构造函数比较合适呢?
假如要创建一个额外方法的引用类型。由于之前说明不建议直接使用String.porotype.addstring方法,
可以使用寄生构造的方式添加:
function mystring(string){
var str=new String(string);
str.addString=function(){
return this+',添加';
}
return str;
}
var box1=new mystring('link');
alert(box1.addString());
在一些安全的环境中,比如禁止使用this和new,这里的this是构造函数里不使用this,这里的new是在外部实例化构造函数时不使用new,
这种创建方式叫稳妥构造函数。
function Box(name,age){
var obj = new Object();
obj.run=function(){
return name+age+"运行中....."
}
return obj
}
var box1=Box('link',53);
alert(box1.run())
ps:稳妥构造函数和寄生类似。
Javascript面对对象. 第四篇的更多相关文章
- Javascript面对对象. 第五篇
继承 继承是面向对象中一个核心的概念.其他正统面向对象语言都会用两种方式实现继承: 一个是接口实现,一个是继承. 而ECMAScript只支持继承,不支持接口实现,而实现继承的方式依靠原型链完成. / ...
- Javascript面对对象. 第三篇
3.字面量 为了让属性和方法很好的体现封装的效果,并且减少不必要的输入原型的创建可以使用字面量. function Box(){} //使用字面量的方法创建原型对象,这里的{}就是对象,是Object ...
- 深入理解javascript作用域系列第四篇——块作用域
× 目录 [1]let [2]const [3]try 前面的话 尽管函数作用域是最常见的作用域单元,也是现行大多数javascript最普遍的设计方法,但其他类型的作用域单元也是存在的,并且通过使用 ...
- 深入理解javascript作用域系列第四篇
前面的话 尽管函数作用域是最常见的作用域单元,也是现行大多数javascript最普遍的设计方法,但其他类型的作用域单元也是存在的,并且通过使用其他类型的作用域单元甚至可以实现维护起来更加优秀.简洁的 ...
- Javascript面对对象. 第一篇
Javascript,有两个种开发模式: 1.函数式(过程化)2.面对对象(oop),面对对象语言有一个标志,就是类,而通过类可以创建任何多个属性和方法,而Ecmascript没有类的概念,因此它的对 ...
- Javascript面对对象. 第二篇
但是还有一个问题,就是识别的问题,因为根本无法搞清楚他们到底是哪个对象的实例. 1.构造函数 function CreateObject(name,age){ //创建一个对象,使用构造函数的对象都是 ...
- javascript面对对象编程 之继承
上一篇博客中为大家介绍了javascript面向对象编程原则的封装,今天为大家介绍继承.在javascript中没有类的概念,全部不能像c#.java语言那样.直接的用类去继承类.比方如今有比方.如今 ...
- javascript面向对象系列第四篇——选项卡的实现
前面的话 面向对象的应用并非只是读几本书那么容易,需要有大量的工程实践做基础才能真正理解并学会使用它.本文将用面向对象的技术来制作一个简单的选项卡 图示说明 由图示结果看到,这是一个非常简单的选项卡. ...
- 深入理解javascript函数系列第四篇——ES6函数扩展
× 目录 [1]参数默认值 [2]rest参数 [3]扩展运算符[4]箭头函数 前面的话 ES6标准关于函数扩展部分,主要涉及以下四个方面:参数默认值.rest参数.扩展运算符和箭头函数 参数默认值 ...
随机推荐
- XCode里的模拟器到底在哪里?我的App被放到哪里了?如何寻找真机的沙盒文件?
一. 开发iOS,必然少不了和XCode这个家伙打交道.平时我们调试自己的App的时候,最常用到的就是模拟器Simulator了,调试的时候,我们的App会自动被XCode安装到模拟器中去,不过: 你 ...
- 485. 找出二进制串中连续的1的个数 Max Consecutive Ones
Given a binary array, find the maximum number of consecutive 1s in this array. Example 1: Input: [1, ...
- IOS 实现TXT文本自动识别编码的方法
from :http://kyoworkios.blog.51cto.com/878347/1344013 TXT识别编码是个复杂的问题.幸好有c/c++的一个库能识别. 库的叫uchardet,可以 ...
- sqlserver 批量删除相同前缀名的表
) DECLARE tmpCur CURSOR FOR SELECT name FROM sys.objects WHERE TYPE='U' AND name LIKE N'HSUPA%' OPEN ...
- Unity3D ——强大的跨平台3D游戏开发工具(二)
第二章 Unity3D的简单预览 每个Unity3D版本都会自带一个Demo源文件.在3.0的正式版中,自带的Demo就是网上展示的那款强大的射击游戏.在一般情况下,您只要第一次 打开Unity3D ...
- ios数据存储——数据库:SQlite3以及第三方库FMDB
[reference]http://blog.csdn.net/mad1989/article/details/9322307 原生数据库:SQlite3 一.必备条件 在ios项目中使用sqlite ...
- Struts2动态方法调用
动态方法就是一个Action对应多个请求,减少Action的数量 1.指定method属性 <action name="addAction" method="add ...
- 云脉推出表格识别API接口可以自助接入
针对如今市场上对于海量票据信息的录入需求,近期厦门云脉技术有限公司推出票据识别相关的产品与服务,更是在云脉OCR SDK开发者平台上上线表格识别API接口,供广大开发者和集成商自助接入.为了降低财务系 ...
- OSG开发概览(转载)
OSG开发概览 1 OSG基础知识 Ø OSG是Open Scene Graphic 的缩写,OSG于1997年诞生于以为滑翔机爱好者之手,Don burns 为了对滑翔机的飞行进行模拟,对open ...
- eclipse修改主题配色
1.Java-->Editor---> Syntax Coloring修改类中的各种代码颜色 2.General-->Editors --->Text Editors