【JavaScript回顾】继承

组合继承

  组合继承(combination inheritance),有时候也叫做伪经典继承,指的是将原型链和借用构造函数的 技术组合到一块,从而发挥二者之长的一种继承模式。其背后的思路是使用原型链实现对原型属性和方 法的继承,而通过借用构造函数来实现对实例属性的继承。这样,既通过在原型上定义方法实现了函数 复用,又能够保证每个实例都有它自己的属性。下面来看一个例子:

  

   <script>
        function Person(name, age, friends) {
            this.name = name;
            this.age = age;
            this.friends = ["Carol", "Seylia"];
            if (typeof this.ShowPerson != "function") {
                this.ShowPerson = function () {
                    var message = "name:" + this.name + "\n\rage:" + this.age + "\r\nfriends:";
                    this.friends.forEach(function (value, index, arr) {
                        message += " " + value;
                    });
                    alert(message);
                }
            }
        }

        function Student(name, age, job) {
            Person.call(this, name, age);
            this.job = job;
        }

        //这里继承了
        Student.prototype = new Person();
        Student.prototype.constructor = Student;

        var s1 = new Student("gck", 26, "Sf");
        s1.friends.push("Core");
        s1.ShowPerson();

        var s2 = new Student("Carol", 28, "Sf");
        s2.ShowPerson();
    </script>

组合继承避免了原型链和借用构造函数的缺陷,融合了它们的优点,成为 JavaScript中常用的继 承模式。而且,instanceof 和 isPrototypeOf()也能够用于识别基于组合继承创建的对象.

  注:不准备说原型链和借用构造,因为这两个缺陷太大,不过有想了解的可以查一下。

寄生组合式继承

面说过,组合继承是 JavaScript 常用的继承模式;不过,它也有自己的不足。组合继承大的 问题就是无论什么情况下,都会调用两次超类型构造函数:一次是在创建子类型原型的时候,另一次是 在子类型构造函数内部。没错,子类型终会包含超类型对象的全部实例属性,但我们不得不在调用子 类型构造函数时重写这些属性,所以我用寄生组合继承:

  所谓寄生组合式继承,即通过借用构造函数来继承属性,通过原型链的混成形式来继承方法。其背 后的基本思路是:不必为了指定子类型的原型而调用超类型的构造函数,我们所需要的无非就是超类型 原型的一个副本而已。本质上,就是使用寄生式继承来继承超类型的原型,然后再将结果指定给子类型 的原型。寄生组合式继承的基本模式如下所示。

<script>
        //如果Object.create浏览器不支持,则用这个方法代替
        function object(o) {
            function F() { }
            F.prototype = o;
            return new F();
        }

        function inheritPrototype(subType, superType) {

            //创建对象
            var prototype = Object.create(superType.prototype);//这个方法IE9+才支持
            //var prototype = object(superType.prototype);

            //增强对象
            prototype.constructor = subType;

            //指定对象
            subType.prototype = prototype;

        }

        function Person(name, age, friends) {
            this.name = name;
            this.age = age;
            this.friends = ["Carol", "Seylia"];
            if (typeof this.ShowPerson != "function") {
                this.ShowPerson = function () {
                    var message = "name:" + this.name + "\n\rage:" + this.age + "\r\nfriends:";
                    this.friends.forEach(function (value, index, arr) {
                        message += " " + value;
                    });
                    alert(message);
                }
            }
        }

        function Student(name, age, job) {
            Person.call(this, name, age);
            this.job = job;
        }

        //这里继承了
        inheritPrototype(Student, Person);

        var s1 = new Student("gck", 26, "Sf");
        s1.friends.push("Core");
        s1.ShowPerson();

        var s2 = new Student("Carol", 28, "Sf");
        s2.ShowPerson();

    </script>

这个例子的高效率体现在它只调用了一次Person构造函数,并且因此避免了在 Student. prototype 上面创建不必要的、多余的属性。与此同时,原型链还能保持不变;因此,还能够正常使用 instanceof 和 isPrototypeOf()。开发人员普遍认为寄生组合式继承是引用类型理想的继承范式。
YUI

时间: 2024-11-05 15:56:01

【JavaScript回顾】继承的相关文章

HTML5移动开发之路(29)—— JavaScript回顾4

本文为 兄弟连IT教育 机构官方 HTML5培训 教程,主要介绍:HTML5移动开发之路(29)-- JavaScript回顾4 一.变量的作用域 JavaScript脚本的执行过程分为两个阶段: 第一阶段,js引擎()先扫描整个javascript代码.当碰到<script>时,会先创建一个全局的活动对象,将<script>中出现的变量的声明,函数的定义保存在活动对 象里面.如果碰到函数,则创建对应的局部活动对象,将函数内部的变量的声明及函数的定义保存在该活动对象里面. 第二阶段

HTML5移动开发之路(30)—— JavaScript回顾5

本文为 兄弟连IT教育 机构官方 HTML5培训 教程,主要介绍:HTML5移动开发之路(30)-- JavaScript回顾5 一.查找 第一种方式:依据id查找 var obj = document.getElementById(id);   //document是HTMLDocument的实例 [html] view plain copy print? <html> <head> <script> function f1(){ var obj = document

HTML5移动开发之路(27)—— JavaScript回顾2

本文为 兄弟连IT教育 机构官方 HTML5培训 教程,主要介绍:HTML5移动开发之路(27)-- JavaScript回顾2 JavaScript面向对象基础知识 1.如何定义一个类,使用如下语法来创建一个类 [javascript] view plain copy print? function Person(name, age){ //习惯上第一个字母大写 //this修饰的变量称为属性 this.name = name; this.age = age; //如果属性值是一个函数,则这个

HTML5移动开发之路(28)—— JavaScript回顾3

本文为 兄弟连IT教育 机构官方 HTML5培训 教程,主要介绍:HTML5移动开发之路(28)-- JavaScript回顾3 一.基本数据类型 number:数字类型 string:字符串 (注意s小写:string是基本类型) boolean:布尔类型   //前三个都有对应的包装类 null:空类型 undefined:未定义类型 测试一: [html] view plain copy print? <html> <!--基本类型测试--> <head> <

javascript类继承

function extend(subClass, superClass) { var f = function() {}; f.prototype = superClass.prototype; subClass.prototype = new f(); subClass.superClass = superClass.prototype; } var parent = function (name, age) { this._name = name; this._age = age; };

javascript深度克隆与javascript的继承实现

1.javascript深度克隆: //注意这里的对象包括object和array function cloneObject(obj){ var o = obj.constructor === Array ? [] : {}; for(var key in obj){ if(obj.hasOwnProperty(key)){ o[key] = typeof obj[key] === "object" ? cloneObject(obj[key]) : obj[key]; } } ret

JavaScript原型继承的陷阱

JavaScript原型继承的陷阱 JavaScript默认采用原型继承.虽然没有类(class)的概念,它的函数(function)可以充当构造器(constructor).构造器结合this,new可以构建出类似Java的类.因此,JavaScript通过扩展自身能模拟类式(class-based)继承. JavaScript和其它面向对象语言一样,对象类型采用引用方式.持有对象的变量只是一个地址,而基本类型数据是值.当原型上存储对象时,就可能有一些陷阱. 先看第一个例子 var creat

浅话javascript的继承

javascript的继承和java或C#的继承是不一样的,后者是基于类的继承,而javascript是通过原型来继承的.所以,先得理一理原型是个什么鬼. 当一个函数对象被创建时,Function构造器产生的函数对象会运行类似这样一些代码:this.prototype={constructor:this},新对象被赋予prototype这样一个属性,它的值是一个包含constructor属性的对象.可以看出,这个constructor指向新对象本身.prototype属性指向的对象自然不会只有c

[JavaScript原型继承理解一]

转:http://www.cnblogs.com/harolei/p/3740354.html 对于JavaScript的继承和原型链,虽然之前自己看了书也听了session,但还是一直觉得云里雾里,不禁感叹JavaScript真是一门神奇的语言.这次经过Sponsor的一对一辅导和自己回来后反复思考,总算觉得把其中的精妙领悟一二了. 1. JavaScript创建对象 在面向对象语言中,通常通过定义类然后再进行实例化来创建多个具有相同属性和方法的对象.但是在JavaScript中并没有类的概念

[ JavaScript ] JavaScript 实现继承.

对于javascript中的继承,由于js中没有后端语言中的类式继承,所以js中的继承,一般都是原型继承(prototype). function P (name){ this.name = name; this.say = function(){ console.log('p'); } } function S (name,id){ this.id = id; this.eat = function(){ console.log('s'); } } S.prototype = P.protot