本文实例汇总了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
而且,子类的构造函数要在定义自己的域之前调用父类构造函数,免得子类的定义被父类覆盖掉。也就是说,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 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又一次。
希望本文所述对大家的javascript程序设计有所帮助。
本文向大家介绍JavaScript 常见的继承方式汇总,包括了JavaScript 常见的继承方式汇总的使用技巧和注意事项,需要的朋友参考一下 原型链机制: 在ECMAscript中描述了原型链的概念,并将原型链作为实现继承的主要方法,其基本思想就是利用原型让一个引用类型继承另一个引用类型的属性和方法。 构造函数和原型还有实例之间的关系: 每个构造函数都有一个原型对象(prototype)
本文向大家介绍老生常谈 关于JavaScript的类的继承,包括了老生常谈 关于JavaScript的类的继承的使用技巧和注意事项,需要的朋友参考一下 其实最一开始学JS的时候就看过继承的实现。当时只是去试着理解从书上看来的代码段而已。今天又重新思考了一下,感觉这是一个思维探索演进的结果。 继承,即复用。 如果抛开继承的固有思想,让b复用a的成员,最简单粗暴的做法, b=a; 那么,问题来了: 对
本文向大家介绍Javascript编程之继承实例汇总,包括了Javascript编程之继承实例汇总的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Javascript编程之继承。分享给大家供大家参考,具体如下: 这篇文字是在看完《Javascript 王者归来》后的整理总结,文章详细章节在 第21章 P537 继承一般要实现以下三层含义: 1)子类实例可以共享父类的方法; 2)子类可以覆盖
本文向大家介绍JavaScript中的继承之类继承,包括了JavaScript中的继承之类继承的使用技巧和注意事项,需要的朋友参考一下 继承简介 在JS中继承是一个非常复杂的话题,比其他任何面向对象语言中的继承都复杂得多。在大多数其他面向对象语言中,继承一个类只需使用一个关键字即可。在JS中想要达到继承公用成员的目的,需要采取一系列措施。JS属于原型式继承,得益于这种灵活性,我们既可以
本文向大家介绍JavaScript中的对象继承关系,包括了JavaScript中的对象继承关系的使用技巧和注意事项,需要的朋友参考一下 我们今天就来看一下继承中的类继承以及类继承和原型继承的混用,所谓类继承,就是使用call或者apply方法来进行冒充继承: 像上面这种就是我们要使用的类继承,用这种继承,我们可以访问类中的方法和属性,但是无法访问父类原型中的方法和属性,这种方法别名冒充继承,顾
本文向大家介绍关于C++中菱形继承和虚继承的问题总结,包括了关于C++中菱形继承和虚继承的问题总结的使用技巧和注意事项,需要的朋友参考一下 前言 菱形继承是多重继承中跑不掉的,Java拿掉了多重继承,辅之以接口。C++中虽然没有明确说明接口这种东西,但是只有纯虚函数的类可以看作Java中的接口。在多重继承中建议使用“接口”,来避免多重继承中可能出现的各种问题。本文将给大家详细介绍关于C++菱形继承