javascript原型问题。继承extendClass.js单例 原型prototypee = baseClass

JS中prototype的用法实例分析
作者:轩脉刃
字体:[ ] 类型:转载 时间:
这篇文章主要介绍了JS中prototype的用法,实例分析了JS中prototype的常见使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下
本文实例讲述了JS中prototype的用法。分享给大家供大家参考。具体分析如下:
JS中的phototype是JS中比较难理解的一个部分
本文基于下面几个知识点:
1 原型法设计模式
在.Net中可以使用clone()来实现原型法
原型法的主要思想是,现在有1个类A,我想要创建一个类B,这个类是以A为原型的,并且能进行扩展。我们称B的原型为A。
2 javascript的方法可以分为三类:
b 对象方法
c 原型方法
例子如下:
function People(name)
this.name=
//对象方法
this.Introduce=function(){
alert("My name is "+this.name);
People.Run=function(){
alert("I can run");
//原型方法
People.prototype.IntroduceChinese=function(){
alert("我的名字是"+this.name);
var p1=new People("Windking");
p1.Introduce();
People.Run();
p1.IntroduceChinese();
3 obj1.func.call(obj)方法
意思是将obj看成obj1,调用func方法
好了,下面一个一个问题解决:
prototype是什么含义?
javascript中的每个对象都有prototype属性,Javascript中对象的prototype属性的解释是:返回对象类型原型的引用。
A.prototype = new B();
理解prototype不应把它和继承混淆。A的prototype为B的一个实例,可以理解A将B中的方法和属性全部克隆了一遍。A能使用B的方法和属性。这里强调的是克隆而不是继承。可以出现这种情况:A的prototype是B的实例,同时B的prototype也是A的实例。
先看一个实验的例子:
function baseClass()
this.showMsg = function()
alert("baseClass::showMsg");
function extendClass()
extendClass.prototype = new baseClass();
var instance = new extendClass();
instance.showMsg(); // 显示baseClass::showMsg
我们首先定义了baseClass类,然后我们要定义extentClass,但是我们打算以baseClass的一个实例为原型,来克隆的extendClass也同时包含showMsg这个对象方法。
extendClass.prototype = new baseClass()就可以阅读为:extendClass是以baseClass的一个实例为原型克隆创建的。
那么就会有一个问题,如果extendClass中本身包含有一个与baseClass的方法同名的方法会怎么样?
下面是扩展实验2:
function baseClass()
this.showMsg = function()
alert("baseClass::showMsg");
function extendClass()
this.showMsg =function ()
alert("extendClass::showMsg");
extendClass.prototype = new baseClass();
var instance = new extendClass();
instance.showMsg();//显示extendClass::showMsg
实验证明:函数运行时会先去本体的函数中去找,如果找到则运行,找不到则去prototype中寻找函数。或者可以理解为prototype不会克隆同名函数。
那么又会有一个新的问题:
如果我想使用extendClass的一个实例instance调用baseClass的对象方法showMsg怎么办?
答案是可以使用call:
extendClass.prototype = new baseClass();
var instance = new extendClass();
var baseinstance = new baseClass();
baseinstance.showMsg.call(instance);//显示baseClass::showMsg
这里的baseinstance.showMsg.call(instance);阅读为“将instance当做baseinstance来调用,调用它的对象方法showMsg”
好了,这里可能有人会问,为什么不用baseClass.showMsg.call(instance);
这就是对象方法和类方法的区别,我们想调用的是baseClass的对象方法
最后,下面这个代码如果理解清晰,那么这篇文章说的就已经理解了:
&script type="text/javascript"&
function baseClass()
this.showMsg = function()
alert("baseClass::showMsg");
this.baseShowMsg = function()
alert("baseClass::baseShowMsg");
baseClass.showMsg = function()
alert("baseClass::showMsg static");
function extendClass()
this.showMsg =function ()
alert("extendClass::showMsg");
extendClass.showMsg = function()
alert("extendClass::showMsg static")
extendClass.prototype = new baseClass();
var instance = new extendClass();
instance.showMsg(); //显示extendClass::showMsg
instance.baseShowMsg(); //显示baseClass::baseShowMsg
instance.showMsg(); //显示extendClass::showMsg
baseClass.showMsg.call(instance);//显示baseClass::showMsg static
var baseinstance = new baseClass();
baseinstance.showMsg.call(instance);//显示baseClass::showMsg
希望本文所述对大家的javascript程序设计有所帮助。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具原型链是采用最主要的继承方式,原理:每一个类(构造器,js中的function)都有一个原型属性(prototype)指向一个原型对象,原型对象有一个构造器(constructor),它又指回到function,是个循环引用,类的每个实例也有一个原型属性(代码无法访问,叫做_proto_),它跟构造器原型指向的是同一个对象,即同一个类的所有实例公用一个原型对象,要实现两个类型的继承,就是将一个类型的原型指向另一个类型的实例,而不再指定原来的默认的原型对象,这样就形成了原型链
子类可以通过原型链获得超类的所有属性和方法,从而实现了继承
实例: function baseClass() { this.baseName = 'baseClass'; }
baseClass.prototype.getbaseClassName = function () { return this.baseName };
function childClass() { this.childName = 'childClass'; }
childClass.prototype = new baseClass();
childClass.prototype.getchildClassName = function () { this.childN }
var instanse = new childClass();
instanse.getbaseClassName();
childClass(及它的实例)的prototype(_proto_)属性不在指向默认的prototype对象,而是Baseclass的实例,这个实例也有个属性(_proto_),它指向的是BaseClass的原型对象,在childClass的实例instanse上查找baseName属性的过程是这样:
首先在instanse自身找,但没找到,然后进入它的原型对象(_proto_属性,此时是BaseClass的实例,不再是默认的原型对象)依然没找到,则进入这个baseclass实例的原型对象(_proto_属性,默认的原型对象上找),终于找到,则返回这个方法的执行结果,
类的原型对象是所有实例共享的,这就造成一个问题,原型对象(父类实例)的属性和方法的改变将影响到所有实例,无论是创建的还是即将创建的
function baseClass() { this.Colors = ['bule', 'red']; }
function childClass() { }
childClass.prototype = new baseClass();
var instanse1 = new childClass();
var instanse2 = new childClass();
//在此实例上对从父类继承过来的属性进行修改
instanse2.Colors.push('green');
var instanse3 = new childClass();
///查看各个实例的colors属性值
alert(instanse1.colors);//red,blue,green
alert(instanse2.colors);//red,blue,green
alert(instanse3.colors);//red,blue,green
可见对于任一个实例来讲,如果修改了继承的属性值,则将影响任何时候创建的实例
另外如果继承的层次过多,则调用最顶层的效率最低
阅读(...) 评论()不错的一篇关于javascript-prototype继承
字体:[ ] 类型:转载 时间:
1.最基本的用法&把ClassA的一个实例赋值给ClassB, ClassB就继承了ClassA的所有属性。 代码入下:
[Ctrl+A 全选 注:]2.从原型继承理论的角度去考虑,& js的原型继承是引用原型,不是复制原型, 所以,修改原型会导致所有B的实例的变化。 代码如下:
[Ctrl+A 全选 注:]3.然而&子类对象的写操作只访问子类对象中成员, 它们之间不会互相影响,因此, 写是写子类&读是读原型(如果子类中没有的话)。
[Ctrl+A 全选 注:]4.每个子类对象都执有同一个原型的引用, 所以子类对象中的原型成员实际是同一个。
[Ctrl+A 全选 注:]5.构造子类时&原型的构造函数不会被执行
[Ctrl+A 全选 注:]6.接下来是致命的,在子类对象中访问原型的成员对象:
[Ctrl+A 全选 注:]7.所以&在prototype继承中&原型类中不能有成员对象!&所有成员必须是值类型数据(string也可以) 用prototype继承有执行效率高,不会浪费内存,为父类动态添置方法后子类中马上可见等的优点。 8.prototype继承是通过把子类的原型对象(prototype)设置成父类的一个实例来进行继承的。 9.prototype继承也有四个比较明显的缺点:   缺点一:父类的构造函数不是像JAVA中那样在给子类进行实例化时执行的,而是在设置继承的时候执行的,并且只执行一次。这往往不是我们希望的,特别是父类的构造函数中有一些特殊操作的情况下。   缺点二:由于父类的构造函数不是在子类进行实例化时执行,在父类的构造函数中设置的成员变量到了子类中就成了所有实例对象公有的公共变量。由于JavaScript中继承只发生在“获取”属性的值时,对于属性的值是String,Number和Boolean这些数据本身不能被修改的类型时没有什么影响。但是Array和Object类型就会有问题。   缺点三:如果父类的构造函数需要参数,我们就没有办法了。   缺点四:子类原本的原型对象被替换了,子类本身的constructor属性就没有了。在类的实例取它的constructor属性时,取得的是从父类中继承的constructor属性,从而constructor的值是父类而不是子类。 10.可以针对prototype的缺点进行改造 比如把它写成Function对象的一个方法,这样用的时候方便。 Function.prototype.Extends&=&function&(parentClass) { &&var&Bs&=&new&Function(); &&Bs.prototype&=&parentClass. &&this.prototype&=&new&Bs(); &&this.prototype.Super&=&parentC &&this.prototype.constructor&=& } 希望各位&js&高手能把更好的方式介绍给大家针对第3,6个
[Ctrl+A 全选 注:]针对继承, Array.prototype&就不能继承&ClassA,ClassB
[Ctrl+A 全选 注:]带参数的继承问题
[Ctrl+A 全选 注:]
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具javascript 原形链方式(prototype) - JavaScript当前位置:& &&&javascript 原形链方式(prototype)javascript 原形链方式(prototype)&&网友分享于:&&浏览:0次javascript 原型链方式(prototype)------------------------------原型链方式(prototype)继承父类的所有方法 ,而 call方式为克隆this调用方式---------------------function sayColor(sPrefix, sSuffix){&&& alert(sPrefix + this.color + sSuffix)}var obj = new Object();obj.color = "red";sayColor.call(obj, "the color is ", ", a ver nice color indeed.");--------------------------------&&&&&&& function ClassA(sColor) {&&&&&&&&&&& this.color = sC&&&&&&&&&&& this.sayhaha = function() {&&&&&&&&&&&&&&& alert(this.color);&&&&&&&&&&& }&&&&&&& }&&&&&&& function ClassC(sColor) {&&&&&&&&&&& ClassA.call(this, sColor);//当前的this为classc自身&&&&&&& }&&&&&&& var classc = new ClassC("black");&&&&&&& alert(classc.color);&&&&&&& classc.sayhaha();---------------------------------apply--------------------------------------function ClassA(sColor){&&& this.color = sC&&& this.sayColor = function(){&&& alert(this.color);&&& }}function ClassB(sColor,sName){&&& ClassA.apply(this, new Array(sColor));&&&&& //第一种Array,当前的this为classb自身&&& //ClassA.apply(this, arguments);&&& &&& //第二种arguments,当前的this为classb自身&&& this.name = sN&&& this.sayName = function(){&&& alert(this.name);&&& }}var Class2 = new ClassB("blue","han");alert(Class2.name);alert(Class2.color);Class2.sayName();Class2.sayColor();---------------------------------delete--------------------------------------&&&&&&& function ClassA(sColor) {&&&&&&&&&&& this.color = sC&&&&&&& }&&& &&&&&&& function ClassC(sColor, sName) {&&&&&&&&&&& this.classA = ClassA;&&&&&&&&&&& this.classA(sColor);&&&&&&&&&&& delete this.classA;&&&&&&& }&&&&&&& &&&&&&& var classc = new ClassC("blue", "han");&&& &&& alert(classc.color);------------------------------原型链方式(prototype)继承父类的所有方法 ,而 call方式为克隆this调用方式---------------------function ClassB(){}ClassB.prototype = new ClassA();ClassB.prototype.name = ""; ------原型链与call不同在于 [ 原型链方式(prototype)继承父类的所有方法, 而 call方式只能继承到this调用方式]---------//这里我们用this调用函数this.fnDisplay();& //这里我们prototype调用函数class.prototype.fnDisplay = function() {}//这里我们prototype调用函数class.prototype.fnDisplay() ------------------------------原型链方式(prototype)继承父类的所有方法 ,而 call方式为克隆this调用方式---------------------function ClassA(sColor){&&& this.color = sC&&& this.saycolor = function() {&&&&&&&&&&&&&&& alert(this.color);&&& }}ClassA.prototype.saycolor1 = function(){&&& alert(this.color);}function ClassB(sColor, sName){&&& ClassA.call(this, sColor)//call方式只能继承到this调用方式&&& this.name = sN}var objB = new ClassB("blue","Nicholas");alert(objB.color);objB.saycolor();objB.saycolor1();------------------------------原型链方式(prototype)继承父类的所有方法 ,而 call方式为克隆this调用方式---------------------function ClassA(sColor){&&& this.color = sC&&& this.aaa = function(){&&& &&& alert("aaa");&&& &&& }}ClassA.prototype.saycolor = function(){&&& alert(this.color);}function ClassB(sColor, sName){&&& ClassA.call(this, sColor);//只能继承this定义的对象及方法,不能继承到prototype定义的方法&&& this.name = sN}ClassB.prototype.sayName = function(){&&& alert(this.name);}var objA = new ClassA("red");var objB = new ClassB("blue","Nicholas");objA.saycolor();objB.aaa();objB.saycolor();//无法调用,因为是原型所以继承不到。objB.sayName();------------------------------原型链方式(prototype)继承父类的所有方法 ,而 call方式为克隆this调用方式---------------------function ClassA(sColor){&&& this.color = sC}ClassA.prototype.saycolor = function(){&&& alert(this.color);}function ClassB(sColor, sName){&&& this.name = sN}ClassB.prototype = new ClassA();//可以全部继承所定义的对象及方法ClassB.prototype.color = "yellow";ClassB.prototype.sayName = function(){&&& alert(this.name);}var objA = new ClassA("red");var objB = new ClassB("blue","Nicholas");objA.saycolor();objB.saycolor();//无法调用,因为是原型所以继承不到。objB.sayName();------------------------------原型链方式(prototype)继承父类的所有方法 ,而 call方式为克隆this调用方式---------------------function ClassA(sColor){&&& this.color = sC&&& this.aaa = function(){&&& &&& alert("aaa");&&& &&& }}ClassA.prototype.saycolor = function(){//这种方式为后期绑定。&&& alert(this.color);}function ClassB(sColor, sName){&&& ClassA.call(this, sColor)//call方式,子类继承不到prototype原型定义的方法。&&& this.name = sN}ClassB.prototype = new ClassA();//原型链方式继承父类的所有方法ClassB.prototype.sayName = function(){&&& alert(this.name);}var objA = new ClassA("red");var objB = new ClassB("blue","Nicholas");//objA.saycolor();//objB.aaa();objB.saycolor();//objB.sayName();------------------------------原型链方式(prototype)继承父类的所有方法 ,而 call方式为克隆this调用方式---------------------function baseClass(){&&& this.showMsg = function()&&& {&&&&&&& alert("baseClass::showMsg");& &&& }& &&& this.baseShowMsg = function()&&& {&&&&&&& alert("baseClass::baseShowMsg");&&& }}baseClass.showMsg = function(){&&& alert("baseClass::showMsg static");}function extendClass(){&&& this.showMsg =function ()&&& {&&&&&&& alert("extendClass::showMsg");&&& }}extendClass.showMsg = function(){&&& alert("extendClass::showMsg static")}extendClass.prototype = new baseClass();instance = new extendClass();instance.showMsg(); //显示extendClass::showMsginstance.baseShowMsg(); //显示baseClass::baseShowMsginstance.showMsg(); //显示extendClass::showMsgextendClass.prototype.baseShowMsg = function(){&&& alert("extendClass::baseShowMsg henry")}instance.baseShowMsg(); //显示baseClass::baseShowMsg henry
12345678910
12345678910
12345678910 上一篇:下一篇:文章评论相关解决方案 12345678910 Copyright & &&版权所有> <JavaScript种的继承>
<JavaScript种的继承>
qiangwang99 & &
发布时间: & &
浏览:1 & &
回复:0 & &
悬赏:0.0希赛币
&JavaScript类的继承&
  1.利用共享prototype实现继承在JavaScript中没有专门的机制来实现类的继承,但可以通过拷贝一个类的prototype到另外一个类来实现继承。一种简单的实现如下:fucntion class1(){  
//构造函数}
  function class2(){  
//构造函数}class2.prototype=class1.class2.prototype.moreProperty1="xxx";class2.prototype.moreMethod1=function(){  
//方法实现代码}var obj=new class2();这样,首先是class2具有了和class1一样的prototype,不考虑构造函数,两个类是等价的。随后,又通过prototype给class2赋予了两个额外的方法。所以class2是在class1的基础上增加了属性和方法,这就实现了类的继承。JavaScript提供了instanceof操作符来判断一个对象是否是某个类的实例,对于上面创建的obj对象,下面两条语句都是成立的:obj instanceof class1obj instanceof class2表面上看,上面的实现完全可行,JavaScript也能够正确的理解这种继承关系,obj同时是class1和class2的实例。事是上不对,JavaScript的这种理解实际上是基于一种很简单的策略。看下面的代码,先使用prototype让class2继承于class1,再在class2中重复定义method方法:&script language="JavaScript" type="text/javascript"&&!--//定义class1function class1(){  
//构造函数}//定义class1的成员class1.prototype={  
m1:function(){     
alert(1);  
}}//定义class2function class2(){  
//构造函数}//让class2继承于class1class2.prototype=class1.//给class2重复定义方法methodclassthod=function(){  
alert(2);}//创建两个类的实例var obj1=new class1();var obj2=new class2();//分别调用两个对象的method方法obj1.method();obj2.method();//--&&/script&从代码执行结果看,弹出了两次对话框“2”。由此可见,当对class2进行prototype的改变时,class1的prototype也随之改变,即使对class2的prototype增减一些成员,class1的成员也随之改变。所以class1和class2仅仅是构造函数不同的两个类,它们保持着相同的成员定义。从这里,相信读者已经发现了其中的奥妙:class1和class2的prototype是完全相同的,是对同一个对象的引用。其实从这条赋值语句就可以看出来://让class2继承于class1class2.prototype=class1.在JavaScript中,除了基本的数据类型(数字、字符串、布尔等),所有的赋值以及函数参数都是引用传递,而不是值传递。所以上面的语句仅仅是让class2的prototype对象引用class1的prototype,造成了类成员定义始终保持一致的效果。从这里也看到了instanceof操作符的执行机制,它就是判断一个对象是否是一个prototype的实例,因为这里的obj1和obj2都是对应于同一个prototype,所以它们instanceof的结果都是相同的。因此,使用prototype引用拷贝实现继承不是一种正确的办法。但在要求不严格的情况下,却也是一种合理的方法,惟一的约束是不允许类成员的覆盖定义。下面一节,将利用反射机制和prototype来实现正确的类继承。
  2.利用反射机制和prototype实现继承
  function class1(){  
//构造函数}class1.prototype={  
method:function(){      alert(1);  
method2:function(){      alert("method2");  
}}function class2(){  
//构造函数}//让class2继承于class1for(var p in class1.prototype){    class2.prototype[p]=class1.prototype[p];}
  //覆盖定义class1中的method方法classthod=function(){  
alert(2);}//创建两个类的实例var obj1=new class1();var obj2=new class2();//分别调用obj1和obj2的method方法obj1.method();obj2.method();//分别调用obj1和obj2的method2方法obj1.method2();obj2.method2();
  从运行结果可见,obj2中重复定义的method已经覆盖了继承的method方法,同时method2方法未受影响。而且obj1中的method方法仍然保持了原有的定义。这样,就实现了正确意义的类的继承。为了方便开发,可以为每个类添加一个共有的方法,用以实现类的继承://为类添加静态方法inherit表示继承于某类Function.prototype.inherit=function(baseClass){   for(var p in baseClass.prototype){     
this.prototype[p]=baseClass.prototype[p];   }}这里使用所有函数对象(类)的共同类Function来添加继承方法,这样所有的类都会有一个inherit方法,用以实现继承,读者可以仔细理解这种用法。于是,上面代码中的://让class2继承于class1for(var p in class1.prototype){    class2.prototype[p]=class1.prototype[p];}可以改写为://让class2继承于class1class2.inherit(class1)这样代码逻辑变的更加清楚,也更容易理解。通过这种方法实现的继承,有一个缺点,就是在class2中添加类成员定义时,不能给prototype直接赋值,而只能对其属性进行赋值,例如不能写为:class2.prototype={  
//成员定义}而只能写为:class2.prototype.propertyName=someVclassthodName=function(){  
本问题标题:
本问题地址:
温馨提示:本问题已经关闭,不能解答。
暂无合适的专家
&&&&&&&&&&&&&&&
希赛网 版权所有 & &&

我要回帖

更多关于 原型prototype 的文章

 

随机推荐