Javascript高级程序设计——14.面向对象与原型(2)

1、创建原型访问prototype有两种方法

(1)构造函数实例方法创建

构造函数:在对象创建或者实例化时候被调用的方法。通常使用该方法来初始化数据成员和所需资源。

构造器Constructor不能被继承,因此不能重写Overriding,但可以被重载Overloading 

function Box(){
		...
    	}

    a、对象名访问prototype;

	var box=new Box();
	//alert(box.prototype);  //使用对象实例无法访问到prototype
	alert(box.__proto__);  //使用对象实例访问prototype指针;
	alert(Box.prototype);
	//使用构造函数(对象名)访问prototype  

    b、box.constructor

	Box.prototype.name='Lee';
	Box.prototype.age=21;
	Box.prototype.run=function(){
		return this.name+this.age+'运行中..';
	};
	var box=new Box();
	alert(box.constructor);
		//结果:function Box(){}
	alert(box.constructor==Object);		//false	
	alert(box.constructor==Box);		//true;


(2)使用字面量方式创建

其中的方括号就是创建了一个新对象

    a、创建一个原型对象

Box.prototype={
		name:'Lee';
		age:21;
		run:function(){
			return this.name+this.age+'运行中...';
		}
	};  

 

    b、重写prototype原型

重写后,之前的将不再存在,即覆盖

Box.prototype={
		age:22;   //这里不会保留之前的任何信息;
	
	};   

    c、box.prototype

	var box=new Box();
	//alert(box.run)
	alert(box.constructor==Object);  //true;  
        alert(box.constructor==Box);     //true;  

区别——

第一种构造函数的方法不可以指向Object,只能指向Box函数

第二种字面量方法既可以指向Box原型,又可以指向Object,(由于字面量花括号{}即表示的为新的     对象)


(2)通过原型prototype创建内置引用扩展(以sort排序为例)

      a、sort()最简单的排序——采用数组方式

	var box=[2,1,3,6,0,9];
	alert(box.sort());

结果:0 1 2 3 6 9


      b、查看sort是否为Array原型对象的方法

	alert(Array.prototype.sort);
	alert(String.prototype.substring); 

      c、内置引用类型扩展;

	String.prototype.addstring=function(){
		return this+'被添加了';
	};
	alert('Lee'.addstring());   //Lee被添加了;

    注意:不推荐用上述扩展对象办法,会导致命名冲突。


(3)原型优缺点

(1)即“共享”

(2)无法保持独立性

若引用类型时,添加或修改实例化都会发生冲突。


2、原型prototype

   (1)全部在原型prototype中定义函数

	function Box(){
	
	}


	Box.prototype={
		constructor:Box,
		name:'Lee',
		age:21,
		family:['哥哥','姐姐','妹妹'],
		run:function(){
			return this.name+this.age+'运行中';
		}
	};


	var box1=new Box();
	alert(box1.family);
	box1.family.push('弟弟');
	//在第一个实例修改后引用类型,保持了共享;


	var box2=new Box();
	alert(box2.family);
	//共享了box1添加后的引用类型的原型;

结果:(1)哥哥、姐姐、妹妹

      (2)哥哥、姐姐、妹妹、弟弟

      (3)哥哥、姐姐、妹妹、弟弟(共享)

上述案例中,由于原型的共享性,导致相互独立性与共享之间的属性无法区分开来,

为了解决这个问题,推荐使用混合模式,即“构造函数+原型模式”,见案例(2)


(2)构造函数+原型模式

要点:在共享的时候选择原型,在独立时选择构造函数

分析:(1)由于name、age相对独立,使用构造函数模式

(2)run方法是一致的,采用原型共享的模式

	//1.保持独立的用构造函数
	function Box(name,age){
		this.name=name;
		this.age=age;
		this.family=['哥哥','姐姐','妹妹'];
	}
	//2.保持共享的用原型;
	Box.prototype={
		constructor:Box,
		run:function(){
			return this.name+this.age+'进行中';
		}
	};


	var box1=new Box('Lee',21);
	alert(box1.family);
	box1.family.push('弟弟');
	alert(box1.family);


	var box2=new Box('Jack',22);
	alert(box2.family);

结果:(1)哥哥、姐姐、妹妹
       (2)哥哥、姐姐、妹妹、弟弟
      (3)哥哥、姐姐、妹妹
    注意:(1)引用类型没有使用原型,所以没有共享;  

          (2)对于原型模式而言,不管是否调用了原型中的共享方法,他都会初始化原型中的方法,
最好的方式将原型与构造函数封装在一起,即“动态原型模式”,见案例(3)


(3)动态原型模式(封装)

    要点:a、将构造函数、原型模式封装在一起,实现了资源的高效性,同时减少内存;

          b、采用typeof关键字、if语句判断减少了初始化的次数,实现了效率的高效性。

//动态原型模式
function Box(name,age){
	this.name=name;
	this.age=age;
	this.family=['哥哥','姐姐','妹妹'];
	
	//判断this.run是否存在;
	if(typeof this.run!='function'){
		alert('原型初始化开始');
		Box.prototype.run=function(){
			return this.name+this.age+'运行中';
		};
		alert('原型初始化结束');
	}
	
}


//原型的初始化,只要第一次初始化即可,没必要每次多初始化,采用if语句判断;
var box1=new Box('Lee',10);


var box2=new Box('Jack',20);

结果:(1)原型初始化开始 原型初始化结束

      (2)原型初始化开始 原型初始化结束(只执行了两次)

注意:使用动态原型模式,注意不可以再用字面量方式重写原型,会切断实例和新原型之间的联系


(4)生构造模式=工厂模式+构造函数

工厂模式——即先创建一个对象object,再返回这个对象,同时为该对添加属性和方法;

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('Lee',21);
alert(box1.run());

  

(5)稳妥构造模式

与寄生构造模式唯一不同点是:稳妥构造模式不适用new关键字

 
  var box1=Box('Lee',21);
		alert(box1.run()); 

  

  


http://www.niftyadmin.cn/n/1659288.html

相关文章

Javascript高级程序设计——14.面向对象与原型(3)

继承 A.继承是面向对象中一个比较核心的概念。 B.正统面向对象语言有两种方式实现继承: (1)接口实现; (2)继承 C.在ECMAScript只支持继承,不支持接口实现, 而实现继承的方式依靠…

python中的matplotlib画几围的图_如何在matplotlib中使用Python绘制4d图

我正在寻找一种使用Python和matplotlib创建四维绘图(曲面加色阶)的方法。我可以使用前三个变量生成曲面,但是我没有成功地为第四个变量添加颜色比例。下面是我的一小部分数据。任何帮助都将不胜感激。谢谢数据子集var1 var2 var3 var410.39 73.32 2.02 28.2611.13 6…

Javascript高级程序设计——15-2.常见的内存泄漏及解决内存泄漏

1、javascript中常见的内存泄漏问题 常见的内存泄漏,第一种情况,大多数由于IE浏览器无法正常关闭导致的内存占用问题; 第二种情况,是即使IE浏览器关闭,也无法释放内存。 (1)给DOM对象添加的属…

java ssh maven_Java-手动搭建SSH(maven版)

创建maven项目把maven项目变为动态网站,步骤如下:项目结构图如下:开始搭建springspringmvcHibernate项目环境版本就不多说了,直接贴出pom.xml文件4.0.0com.kasparcom.kasparwar0.0.1-SNAPSHOTUTF-82.5.104.3.8.RELEASE5.1.7.Final…

15.处理图像(案例:验证码+缩略图+加载系统字体+加载已有的图片)

在PHP5中的php.ini文件中包含了GD扩展包,只需要取代平GD扩展包的相应注释就可以正常使用。 PHP5包含的GD库正是升级的GD2库,其中包含了支持真彩图像处理的有用的JPG功能, 生成的图形,通过PHP的文档格式进行存放,还可以…

Jquery——Day7(Ajax提交表单)

1、创建数据库 名称为“zhiwen”&#xff0c;表为id、user、pass、email、sex、birthday、date 创建php文件&#xff1a;config.php、add.php、is_user.php &#xff08;1&#xff09;config.php <?php//防止乱码&#xff0c;初始化设置&#xff1b;header(Content-Type…

java监听在线人数_java监听器实现在线人数统计

本文实例为大家分享了java在线人数统计的具体代码&#xff0c;供大家参考&#xff0c;具体内容如下1. 项目结构2. 代码package com;import javax.servlet.ServletContextEvent;import javax.servlet.ServletContextListener;import javax.servlet.annotation.WebListener;/*** …

java 同余法产生随机数_线性同余法生成为随机数

线性同余方法(LCG)是个产生伪随机数的方法。它是根据递归公式&#xff1a;其中是产生器设定的常数。LCG的周期最大为&#xff0c;但大部分情况都会少于M。要令LCG达到最大周期&#xff0c;应符合以下条件&#xff1a;的所有质因子的积能整除&#xff1b;若是4的倍数&#xff0c…