浅谈JavaScript中继承的实现

  谈到js中的面向对象编程,都有一个共同点,选择原型属性还是构造函数,两者各有利弊,而就片面的从js的对象创建以及继承的实现两个方面来说,官方所推荐的是两个相结合,各尽其责,各取其长,在前面的例子中,我已就在JavaScript中对象创建的方法做了一些总结,下面就其继承来道说一二:

 

1:原型链继承:

   每一个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象内部的指针(默认的原型,所有默认类型都继承了Object,而这个继承也是用过原型链实现)
function SuperType(){
            this.property = true;
        }

        SuperType.prototype.getSuperValue = function(){
            return this.property;
        };
        function SubType(){
            this.subproperty = false;
        }

        //继承SuperType
        SubType.prototype = new SuperType();

        SubType.prototype.getSubValue = function(){
            return this.subproperty;
        };
        var instance = new SubType();
        alert(instance.property);

        alert(instance.getSuperValue());
        alert(instance.getSubValue());

原型继承的问题:

   1:原型属性被所有实例所共享   一个改变,其余跟着改变。   2:在创建子类型的实例时,不能向超类型的构造函数中传递参数总结:实践中很少会单独使用原型链
            (这似乎和对象创建时的问题如出一辙)

 

2:借用构造函数创建:

        function SuperType(){
            this.colors = ["red","blue","green"];
        }
        function SubType(){
//            继承了SubType
            SuperType.call(this);
        }
        var instance1 = new SubType();
        instance1.colors.push("black");
        alert(instance1.colors);   //["red", "blue", "green", "black"]

        var instance2 = new SubType()
        alert(instance2.colors);   //["red", "blue", "green"]没哟随某个实例
                                    //的更改而更改
//--------------------------------------------------------------------------
//        参数传递:
         function SuperType(name){
            this.name = name;
        }
        function SubType(){
//            继承了SuperType,同时还传递了参数
            SuperType.call(this , "Nicholas");
//            实例属性
            this.age = 29;
        }
        var instance = new SubType();
        alert(instance.name);  //Nicholas
        alert(instance.age);  //29

缺点:方法都在构造函数里面定义,因此函数复用就无从谈起(什么意思呢:摸索中)。

 

组合继承:

//        组合继承:
        function SuperType(name){
            this.name = name;
            this.colors = ["red","blue","green"];
        }

        SuperType.prototype.sayName = function(){
            alert(this.name);
        }

        function SubType(name , age){
            //继承属性:  调用构造函数
            SuperType.call(this , name);//第一次调用SuperType()
            this.age = age;
        }

        //继承方法:
        SubType.prototype = new SuperType(); //第二次调用SuperType()
        SubType.prototype.constructor = SubType;
        SubType.prototype.sayAge = function(){
            alert(this.age);
        };

        var instance1 = new SubType("Nicholas",29);
        instance1.colors.push("black");
        alert(instance1.colors);
        instance1.sayName();
        instance1.sayAge();

        var instance2 = new SubType("Greg",27);
        alert(instance2.colors);
        instance2.sayName();
        instance2.sayAge();

  自然,这种组合式创建也有其不到之处,即来两次调用了SuperType构造函数,使得实例属性colors和name的重复创建,后一次创建的自然会覆盖前面的。

随引出<寄生组合式继承>

上代码:

//寄生组合式继承:
        function inheritPrototype(subType , superType){
            var prototype = Object(superType.prototype);  //创建对象原型的一
//个副本

//为创建的副本添加constructor属性,使其指向自己的构造函数
            prototype.constructor = subType;

//将新创建(副本)的对象赋给子类型的一个原型
            subType.prototype = prototype;
        }

        function SuperType(name){
            this.name = name;
            this.colors = ["red","blue","green"];
        }
        SuperType.prototype.sayName = function(){
            alert(this.name);
        };
        function SubType(name, age){
            SuperType.call(this,name);

            this.age = age;
        }
        inheritPrototype(SubType , SuperType);
        SubType.prototype.sayAge = function(){
            alert(this.age);
        };

从代码中,咋们可以看出,值调用了一次SuperType的构造函数,固然就没有什么多余的不必要的属性创建。

时间: 2024-12-26 05:51:34

浅谈JavaScript中继承的实现的相关文章

浅谈JavaScript中的原型模式

在JavaScript中创建对象由很多种方式,如工厂模式.构造函数模式.原型模式等: <pre name="code" class="html">//工厂模式 function createPerson(name,age,job) { var o = new Object; o.name = name; o.age = age; o.job = job; o.sayName = function() { alert(this.name); } retur

浅谈Javascript中的原型、原型链、继承

构造函数,原型,实例三者的关系 构造函数: 构造函数是创建对象的一种常用方式, 其他创建对象的方式还包括工厂模式, 原型模式, 对象字面量等.我们来看一个简单的构造函数: function Product (name, role){ //构造函数的命名约定第一个字母使用大写的形式! this.name = name; this.role = role; } ( 1 ) 每一个构造函数都有一个prototype属性,我们可以在Chorme控制台中打印出Product.prototype属性. (

浅谈js中继承的理解和实现

一.前言 java.C#等正统面向对象语言都会提供类似extend之类的处理类的继承的方法,而javascript并没有提供专门的方法用于继承,在javascript中使用继承需要一点技巧.js中实例的属性和行为是由构造函数和原型两部分组成的,js的继承也分为这两部分.下面给大家分享一下在js中如何实现继承,讲的不对的地方望大家指正! 二.继承构造函数中的属性和行为 我们定义两个类Animal和Bird类,来实现js中类的继承. //定义Animal类 function Animal(name)

浅谈javascript中的闭包

引入定义:闭包只有权访问另一个函数中的作用域中的函数. 简单点说,就是当某函数a执行完毕后,闭包不会使得GC(JavaScript的回收机制)去回收a所占用的资源,因为a的内部函数b的执行需要依赖a中的变量. 代码示例: window.onload = function(){ function createComparisonFunction(propertyName){ return function(object1, object2){ var value1 = object1[proper

浅谈javascript中的For in语法

相信大家都使用过javascript中的for循环,主要用来遍历数组对象,方便执行重复操作,体现代码的重用性.但是,应为数组的索引一般是整 型的数字,当遇到JSON对象或者object对象时,就不能使用for循环遍历了,应当使用for in函数遍历对象,这里就谈谈个人对for in的理解. 首先,虽然叫For in语法但关键字还是用for,这个语法还可以用来遍历对象,拿到的是对象的属性名称,然后通过对象名[属性名称]就可以拿到对象.个人觉得,理解这个语法的本质,关键在于理解每次循环得到的到底是什

浅谈javascript中的call、apply、bind

apply.call 在 javascript 中,call 和 apply 都是为了改变某个函数运行时的上下文(context)而存在的,换句话说,就是为了改变函数体内部 this 的指向. JavaScript 的一大特点是,函数存在「定义时上下文」和「运行时上下文」以及「上下文是可以改变的」这样的概念. 先来一个栗子: function fruits() {} fruits.prototype = { color: "red", say: function() { console

浅谈JavaScript中的函数问题

前面的话:JavaScript可运行在所有主要平台的主流浏览器上,也可运行在每一个主流操作系统的服务器端上.所以呢,要想成为一名优秀的全栈工程师,必须懂得JavaScript语言.这是我整理的JS的部分函数问题,供大家参考借阅,有不妥的地方也请多多指教. 1.函数的三要素    1.1 函数的功能   1.2 函数的参数 a. 形参——定义函数的时候,没有实际的值,给实参占位 b. 实参——调用函数的时候,有实际的值: c. 当调用函数的时候会把实参复制一份传递给函数 d. 函数调用的时候,实参

浅谈javascript中的包装对象

javascript中的对象类型分为内置类型和对象类型,其中内置类型包括sting number boolean null undefined五种:对象类型包括Array Function regExp Date 等等,统称为Object类型.我们知道在一个对象中包含一系列属性名/属性值的集合,可以通过"."来访问对象的属性或方法,如: 1 window.onload=function(){//可执行代码} 但我们常常可以看到这样的代码: 1 var str="hello w

A1—浅谈JavaScript中的原型

原型是什么?想要了解这个问题,我们就必须要知道对象. 对象 根据w3cschool上的介绍:对象只是带有属性和方法的特殊数据类型. 我们知道,数组是用来描述数据的.其实呢,对象也是用来描述数据的.只不过有一点点的区别,那就是数组的下标只能是数字.所以,数组最好只用来装同样意义的内容.比如说[1,2,3,4,5]或者["a","b","c","d","e"]等.因为他们的表达的含义是一样的.那么如何表达含义不