不错的一篇关于javascript-prototype继承

1.最基本的用法 把ClassA的一个实例赋值给ClassB,
ClassB就继承了ClassA的所有属性。
代码入下:

function ClassA()
{
this.a='a';
}
function ClassB()
{
this.b='b';
}
ClassB.prototype=new ClassA();
var objB=new ClassB();
for(var p in objB)document.write(p+"
");

[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]

2.从原型继承理论的角度去考虑, 
js的原型继承是引用原型,不是复制原型,
所以,修改原型会导致所有B的实例的变化。
代码如下:

function ClassA()
{
this.a='a';
}
function ClassB()
{
this.b='b';
}
ClassB.prototype=new ClassA();
var objB=new ClassB();
alert(objB.a);
ClassB.prototype.a='changed!!';
alert(objB.a);

[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]

3.然而 子类对象的写操作只访问子类对象中成员,
它们之间不会互相影响,因此,
写是写子类 读是读原型(如果子类中没有的话)。

function ClassA()
{
this.a='a';
}
function ClassB()
{
this.b='b';
}
ClassB.prototype=new ClassA();
var objB1=new ClassB();
var objB2=new ClassB();
objB1.a='!!!';
alert(objB1.a);
alert(objB2.a);

[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]

4.每个子类对象都执有同一个原型的引用,
所以子类对象中的原型成员实际是同一个。

function ClassA()
{
this.a=function(){alert();};
}
function ClassB()
{
this.b=function(){alert();};
}
ClassB.prototype=new ClassA();
var objB1=new ClassB();
var objB2=new ClassB();
alert(objB1.a==objB2.a);
alert(objB1.b==objB2.b);

[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]

5.构造子类时 原型的构造函数不会被执行

function ClassA()
{
alert("a");
this.a=function(){alert();};
}
function ClassB()
{
alert("b");
this.b=function(){alert();};
}
ClassB.prototype=new ClassA();
var objB1=new ClassB();
var objB2=new ClassB();

[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]

6.接下来是致命的,在子类对象中访问原型的成员对象:

function ClassA()
{
this.a=[];
}
function ClassB()
{
this.b=function(){alert();};
}
ClassB.prototype=new ClassA();
var objB1=new ClassB();
var objB2=new ClassB();
objB1.a.push(1,2,3);
alert(objB2.a);
//所有b的实例中的a成员全都变了!!

[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]

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.prototype;
  this.prototype = new Bs();
  this.prototype.Super = parentClass;
  this.prototype.constructor = this;
}

希望各位 js 高手能把更好的方式介绍给大家
针对第3,6个

function ClassA()
{
this.a=[]
this.aa=100;
}

function ClassB()
{
this.b=function(){return "classbb"};
}

ClassB.prototype=new ClassA();

var objB1=new ClassB();
var objB2=new ClassB();

objB1.a.push(1,2,3);
objB1.aa=10100
alert(objB2.a);
alert(objB2.aa);

[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]

针对继承,
Array.prototype 就不能继承 ClassA,ClassB

function ClassA()
{
this.a=[]
this.aa=100;
}

function ClassB()
{
this.b=function(){return "classbb"};
}
ClassB.prototype=new ClassA();
Array.prototype= new ClassB();
var _array= new Array()
alert(_array.b())

[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]

带参数的继承问题

aaa

function ClassB()
{
this.b=function(){return "classbb"};
}

function ClassC(R){
el=document.getElementById(R)
return el
}

ClassB.prototype=new ClassC()
var st=new ClassB()
alert(st("a").innerHTML)

[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]

(0)

相关推荐

  • JavaScript是如何实现继承的(六种方式)

    前言:大多OO语言都支持两种继承方式: 接口继承和实现继承 ,而ECMAScript中无法实现接口继承,ECMAScript只支持实现继承,而且其实现继承主要是依靠 原型链 来实现. 1.原型链 基本思想:利用原型让一个引用类型继承另外一个引用类型的属性和方法. 构造函数,原型,实例之间的关系:每个构造函数都有一个原型对象,原型对象包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针. 原型链实现继承例子: function SuperType() { this.property

  • 深入了解javascript中的prototype与继承

    通常来说,javascript中的对象就是一个指向prototype的指针和一个自身的属性列表.javascript创建对象时采用了写时复制的理念.只有构造器才具有prototype属性,原型链继承就是创建一个新的指针,指向构造器的prototype属性.prototype属性之所以特别,是因为javascript时读取属性时的遍历机制决定的.本质上它就是一个普通的指针. 构造器包括: 1.Object2.Function3.Array4.Date5.String 下面我们来举一些例子吧 复制代

  • javascript prototype的深度探索不是原型继承那么简单第1/3页

    1 什么是prototype JavaScript中对象的prototype属性,可以返回对象类型原型的引用.这是一个相当拗口的解释,要理解它,先要正确理解对象类型(Type)以及原型(prototype)的概念.         前面我们说,对象的类(Class)和对象实例(Instance)之间是一种"创建"关系,因此我们把"类"看作是对象特征的模型化,而对象看作是类特征的具体化,或者说,类(Class)是对象的一个类型(Type).例如,在前面的例子中,p1和

  • Extjs学习笔记之八 继承和事件基础

    这里接口的意思是Observable实际上起了一个抽象类的作用,Extjs中有大量的组件都是继承自这个类的.这个类提供了一些基本的方法比如addEvents,addlistener,fireEvent等等. 本文暂时不介绍如何使用extjs的组件响应事件,而是介绍Extjs的事件的一些实现原理.整个Extjs框架都是以一种面向对象的方式开发的,所以理解Javascript中的继承也很重要.我前面的一篇文章 补点基础:Javascript中的类和闭包 也是为这篇做准备.另外,博客园内还有一个写的很

  • js中继承的几种用法总结(apply,call,prototype)

    一,js中对象继承 js中有三种继承方式 1.js原型(prototype)实现继承 复制代码 代码如下: <SPAN style="BACKGROUND-COLOR: #ffffff"><SPAN style="FONT-SIZE: 18px"><html>  <body>  <script type="text/javascript">      function Person(na

  • js的2种继承方式详解

    js中继承可以分为两种:对象冒充和原型链方式 一.对象冒充包括三种:临时属性方式.call()及apply()方式1.临时属性方式 复制代码 代码如下: function Person(name){     this.name = name;     this.say = function(){          alert('My name is '+this.name);     }}function F2E(name,id){     this.temp = Person;     thi

  • 前端开发必须知道的JS之原型和继承

    一. 原型与构造函数 Js所有的函数都有一个prototype属性,这个属性引用了一个对象,即原型对象,也简称原型.这个函数包括构造函数和普通函数,我们讲的更多是构造函数的原型,但是也不能否定普通函数也有原型.譬如普通函数: 复制代码 代码如下: function F(){ alert(F.prototype instanceof Object) //true; } 构造函数,也即构造对象.首先了解下通过构造函数实例化对象的过程. 复制代码 代码如下: function A(x){ this.x

  • 实现JavaScript中继承的三种方式

    一.原型链继承 在原型链继承方面,JavaScript与java.c#等语言类似,仅允许单父类继承.prototype继承的基本方式如下: 复制代码 代码如下: function Parent(){} function Child(){} Child.prototype = new Parent(); 通过对象Child的prototype属性指向父对象Parent的实例,使Child对象实例能通过原型链访问到父对象构造所定义的属性.方法等. 构造通过原型链链接了父级对象,是否就意味着完成了对象

  • JS继承--原型链继承和类式继承

    什么是继承啊?答:别人白给你的过程就叫继承. 为什么要用继承呢?答:捡现成的呗. 好吧,既然大家都想捡现成的,那就要学会怎么继承! 在了解之前,你需要先了解构造函数.对象.原型链等概念...... JS里常用的两种继承方式: 原型链继承(对象间的继承)类式继承(构造函数间的继承) 原型链继承: 复制代码 代码如下: //要继承的对象var parent={name : "baba" say : function(){ alert("I am baba");}} //

  • JavaScript的继承实现小结

    最近在忙前端的工作,因为之前做.net和php的开发比较多,前端开发喜欢把库拿来就用,几次事实证明,不懂原理,连改代码也改不好,所以还是下定决心研究下JavaScript的几个技术难点. 0x1.JavaScript的对象和构造函数 定义一个JavaScript对象可以这么定义 var a = { x : 1, y : 2, add : function () { return this.x + this.y; }, mul : function () { return this.x * thi

随机推荐