javascript中的继承用法

本文实例汇总了javascript关于继承的用法,希望本文所述对大家的javascript程序设计有所帮助。分享给大家供大家参考。具体如下:
代码如下:

/**
* 实现子类继承父类,但不会产生多余的属性和方法
* @returns {Function}
*/
define(function(){
return function(subType, superType){
var proto = new Object(superType.prototype);
proto.constructor = subType;
subType.prototype = proto;
};
});
//——————————————————————————
define(function(){
function ostring(s)
{
this.str = s;
this.length = this.str.length;
}
ostring.prototype.show = function(){
alert(this.str);
};
return ostring;
});
//——————————————————————————
define([‘inherit‘, ‘ostring‘], function(inherit, ostring){
function wstring(s){
//用call实现调用父类构造函数
ostring.call(this, s);
this.chlength = 2 * s.length;
}
//继承其他的属性
inherit(wstring, ostring);
wstring.prototype.add = function(w)
{
alert(this.str + w);
};
return wstring;
});

一、用function实现:

function Person(name) {
    this.name = name;
}
Person.prototype.getName = function() {
    return this.name;
}
function Author(name, books) {
    this.inherit=person;
    this.inherit(name);
    this.books = books;

}
var au=new Author("dororo","Learn much");
au.name

或者同等效力的:

function Person(name) {
    this.name = name;
}
Person.prototype.getName = function() {
    return this.name;
}
function Author(name, books) {
    Person.call(this, name);
    this.books = books;

}
var au=new Author("dororo","Learn much");
au.getName

由于这只是将this作为参数,调用父类Person的构造函数,把赋予父类的所有域赋予Author子类,所以任何父类Person构造函数之外的定义的域(原型prototype),子类都不会继承。所以上面例子中,au.getName将是没有被定义的(undefined),因为getName是在Person的原型对象中定义的。

而且,子类的构造函数要在定义自己的域之前调用父类构造函数,免得子类的定义被父类覆盖掉。也就是说,Author定义属性book要在Person.call之后,否则会被Person中属性覆盖。同时,在子类中也最好不要用prototype来定义子类的函数域,因为在一个子类被new,实例化之后就要执行prototype,然后才是调用父类的构造函数,这样也容易被父类的属性覆盖掉。

二、用prototype实现:

function Person(name) {
    this.name = name;
}
Person.prototype.getName = function() {
    return this.name;
}
function Author(name, books) {
    this.books = books;
}
Author.prototype=new Person(name);
Author.prototype.constructor=Author;
Author.prototype.getBooks = function() {
    return this.books;
}
var au1=new Author("dororo1","Learn much");
var au2=new Author("dororo2","Learn less");
alert(au1.getName());
alert(au2.getName());

这种方法避免了function实现中,无法继承prototype的问题。因为 Author.prototype=new Person(name);new Person()实例会调用Person构造和原型的所有属性。但是缺点是已经实例化了Author.prototype。所以当子类实例化的时候,所有非基本数据类型都是reference copy。所以上面例子中,无论实例au1,还是au2返回的值都是dororo1.

三、用“混合”实现

function Person(name) {
    this.name = name;
}
Person.prototype.getName = function() {
    return this.name;
}
function Author(name, books) {
    this.base = new Person(name);
    for(var key in this.base){
        if(!this[key]){
           this[key]=this.base[key];
           }
           }
    this.book=books;
}
var au1=new Author("dororo1","work");
var au2=new Author("dororo2","play");
alert(au1.getName());
alert(au2.getName());
au1.book;
au2.book;
 

属于扩展,把父类的所有域都拷贝到子类。完全没有上述两方面的问题。
寄生组合模式)

JS的继承包括属性的继承和方法的继承,他们分别通过不同的方法来实现。
1.属性的继承

属性的继承通过改变函数的执行环境来实现的。而改变函数的执行环境可以使用call()和apply()两种方法来实现。

我们首先创建一个Animal“类”(因为JS中没有类的概念,这里只是一个模拟,它实际上只是一个Function函数对象)。

function Animal(typeName) {
//为当前方法的执行环境(this)添加一个属性typeName
//但是执行环境(this)要执行这个函数的时候才能确定
this.typeName = typeName;
this.colors = ["red","while"];
}
//想函数的原型里 添加 两个(对象共享的)的方法
Animal.prototype.Shout = function () { alert("我是:--" + this.typeName);};
Animal.prototype.Eat = function () { alert("我是:--" + this.typeName) };
//--定义一个狮子--“类”(其实就是一个函数)
function Lion(tn) {
//--执行Animal方法,并通过apply的第一个参数 修改了Animal的执行环境为Lion的this
//同样的,Lion的this,也要在执行的时候才能确定是谁
Animal.apply(this,["狮子"]);//--继承了父类的变量属性,this因为是new了Lion,this是Lion
}
Lion.prototype = Animal.prototype; //继承父类的方法,搞定--但是这写不好,当子类再添加方法时候,父类同样也有此方法,这是指针引用
Lion.prototype.Hunt = function () {
alert("我是:狮子,我要去捕猎~~·~");
}
var aminm = new Animal();
aminm.Hunt(); //---可以访问到子类的方法,这样就不好了
//----那么如何解决这个问题呢》??????
//---解决方案:继承方法时候可以这样写:
Lion.prototype = new Animal();//继承父类的方法,把Animal对象赋给了prototype原型,其实它里面也有属性
var lion = new Lion(); //new 关键字除了创建的,还会修改Lion对象的执行环境为Lion对象本身
// ---换句话说,就是new完了之后,Lion函数里的this就是Lion函数本身了,然后调用Lion函数

new关键字作用解析:

而new关键字是十分伟大的,在上段代码中,new关键字完成了以下几项工作:

  1. 开辟堆空间,以准备存储Lion对象
  2. 修改Lion对象本身的执行环境,使得Lion函数的this指向了Lion函数对象本身。
  3. 调用Lion“类”的“构造函数”,创建Lion对象
  4. 将Lion函数对象的堆地址赋值给变量l,这个时候l就指向了这个Lion函数对象

    lion.Shout();
    lion.Eat();

    但是这种继承有个缺点:就是父类的构造函数的被调用了两次,call一次,然后new又一次。

时间: 2024-12-11 02:16:39

javascript中的继承用法的相关文章

JavaScript学习13 JavaScript中的继承

JavaScript学习13 JavaScript中的继承 继承第一种方式:对象冒充 <script type="text/javascript"> //继承第一种方式:对象冒充 function Parent(username) //父类对象 { this.username = username; //下面的代码最关键的部分就是将子对象的this传递给了父对象 this.sayHello = function() { alert(this.username); } } f

javascript中NaN的用法

NaN是一个特殊的数值,任何数值除以0会返回NaN,不会影响其他代码的执行(其实为0/0为NaN,正数除以0得到infinity,负数除以0得到负的infinity) 它的特点为: 1.任何涉及NaN的操作都返回NaN 2.NaN与任何值都不相等,包括NaN 它涉及到的函数为isNaN();该函数接受一个参数,该参数可以是任何类型 javascript中NaN的用法,布布扣,bubuko.com

JavaScript中的继承(原型链)

一.原型链 ECMAScript中将原型链作为实现继承的主要方法,基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法. 实例1: function SupType() { this.property = true; } SupType.prototype.getSupvalue = function() { return this.property; }; function SubType() { this.subproperty = false; } //原型对象等于一个类型的实例

javascript 中各种继承方式的优缺点 (转)

javascript中实现继承的方式有很多种,一般都是通过原型链和构造函数来实现.下面对各种实现方式进行分析,总结各自的优缺点. 一 原型继承 let Super = functioin(name) { this.name = name; this.setName = (newName) => { this.name = name; }; this.getName = () => { return this.name; } } let Sub = function(sex) { this.se

JavaScript中的继承机制

JavaScript到底是不是面向对象的?! 有人说是,有人说基于对象更准确,因为JavaScript没有类.不去管它,但JavaScript确实提供了一些面向对象的机制. 本文主要讨论JavaScript中的继承.继承,简单来说,就是让子类获得父类的属性和方法,以达到共享和复用的目的. 在开始继承之前,首先需要创建父类.为了后续讨论的需要,我分别为父类创建了私有对象.实例对象.引用对象和两个实例方法. 创建父类的代码如下: // 父类实例的构造函数 function Pet(name,soun

javascript 中实现继承的六种方式

javascript 中对于继承的描述: 许多面向对象语言都支持两种继承的方式:接口继承和实现继承.接口继承只继承方法签名,而实现继承则继承实际的方法.在 javascript 中由于函数没有签名也就无法实现接口继承,而只支持实现继承,而且实现继承主要通过原型链来实现的. 先引述下官方文档对于原型链的描述:其基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法.要理解这个概念要先弄清楚构造函数,原型,和实例的关系:每个构造函数(只要是函数)都有一个 prototype 属性该属性指向一

javascript中实现继承的几种方式

javascript中实现继承的几种方式 1.借用构造函数实现继承 function Parent1(){ this.name = "parent1" } function Child1(){ Parent1.call(this); this.type = "child1"; } 缺点:Child1无法继承Parent1的原型对象,并没有真正的实现继承(部分继承) 2.借用原型链实现继承 function Parent2(){ this.name = "p

JavaScript中的继承

在JavaScript中没有Java中的exends关键字,只能通过其他的方式来实现继承关系. 1) 对象冒充 1 function Parent(username) 2 { 3 this.username = username; 4 5 this.sayHello = function() 6 { 7 alert(this.username); 8 } 9 } 10 11 function Child(username, password) 12 { 13 //下面三行代码是就是实现了Chil

JavaScript 中的继承

继承是 OO 语言中的一个最为人津津乐道的概念.许多 OO 语言都支持两种继承方式:接口继承和实现继承.接口继承只继承方法签名,而实现继承则继承实际的方法.由于函数没有签名,在 ECMAScript 中无法实现接口继承. ECMAScript 只支持实现继承,而且其实现继承主要是依靠原型链来实现的. 组合继承时 JavaScript 中常用的继承模式,而寄生组合式继承克服了组合继承的缺点,被认为是引用类型最理想的继承范式. 以下是<JavaScript高级程序设计>中介绍的继承方式: