[技术学习]js继承

  今天又看了一遍js的面向对象方面的知识,重点看了继承相关内容,已经记不得看了第几次这个内容,终于觉得自己好像懂了,特记录下来过程。

  js面向对象继承分为两大类,主要分为对象继承和非对象继承(拷贝继承),这次主要谈对象继承。对象继承主要有两种:原型继承和对象冒充继承。

  一、原型继承,将子类的原型引用父类的实例,从而达到将子类的原型与父类的原型和父类的构造函数关联起来的目的。

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

    function Student(age){
        this.age=age;
    }
    Student.prototype=new Person(‘zhangsan‘);//子类构造函数指向父类实例
    Student.prototype.constructor=Student;//上一步指向父类实例时候,构造函数也指向父类,此处还原

    var s=new Student(20);
    alert(s.age);   //20
    s.sayName();    //zhangsan  

  原型继承可以有效的将父类的原型和父类的构造函数里的方法均复制给子类,但是由于子类的构造函数必须指向父类实例,因此父类的成员变量无法通过子类进行实例化,如上述例子,name只能为zhangsan,无法进行子类初始化时候设置。因此我们使用第二种方法来解决此问题。

  二、对象冒充法:

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

    function Student(name,age){
        Person.call(this,name);//此处使用call进行对象冒充,将name初始化
        this.age=age;
    }

    var s=new Student(‘zhangsan‘,20);
    alert(s.name)//zhangsan
    alert(s.age);   //20
    s.sayName();    //error 不是一个方法  

   Person.call(this,name)对象冒充,本质是使用执行s.Person(name),将Student作为执行环境,因此this.name将赋值给Student的实例s,但是我们看到s.sayName()方法执行中报错,因此此方式无法将原型赋值给子类。

  三、混合继承,结合了原型继承和对象冒充继承的优点,解决了两者的不足。

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

    function Student(name,age){     //对象冒充
        Person.call(this,name);//此处使用call进行对象冒充,将name初始化
        this.age=age;
    }  //原型继承
    Student.prototype=new Person();//子类构造函数指向父类实例,与直接原型继承不同,此处不需要传递参数
    Student.prototype.constructor=Student;//上一步指向父类实例时候,构造函数也指向父类,此处还原

    var s=new Student(‘zhangsan‘,20);
    alert(s.name)   //zhangsan  属性成功继承
    alert(s.age);   //20
    s.sayName();    //zhangsan  原型成功继承

 混合继承完美的解决了原型和属性的继承,但是我们发现继承中父类的属性在对象冒充和原型继承中都会被引用,如果属性很多会造成大量重复引用工作,因此参考extjs的原型设计,对继承进行优化。 

四、优化,设计思想核心为:

1、在extend方法,建立中转函数,将中转函数的原型指向父类原型,此时中转函数只有原型,无属性,对中转函数进行实例化,并赋值给子类,成功过滤掉父类的属性。

2、将父类的原型进行保留,可以对子类定义中的父类进行解耦,也可以在子类覆盖父类后通过引用再次调用父类方法

    function extend(sub,sup){
            //建立中转函数,使用原型继承
            var F=new Function();
            //将
            F.prototype=sup.prototype;
            sub.prototype=new F();

            sub.prototype.constructor=sub//还原构造器
            //保留父类原型对象,方便解耦,也可以获取用来父类
            sub.superClass=sup.prototype

        }
        function Person(name,age){
            this.name=name;
            this.age=age;
        }
        Person.prototype.id=10;
        Person.prototype.sayName=function(){
           alert("person")
        }

        function Stu(name,age,no){
            //使用superClass进行解耦
            Stu.superClass.constructor.call(this,name,age);
            this.no=no;

        }
        //Stu.prototype=new Person();
        extend(Stu,Person);

        Stu.prototype.sayName=function(){
           alert("student")
        }

        var s=new Stu(‘zhangsna‘,10,100);

        //s.sayName();
        Stu.superClass.sayName.call(s);

通过深拷贝建立继承关系为jquery的继承实现方法,此次暂不讨论。

时间: 2024-10-19 03:35:24

[技术学习]js继承的相关文章

[技术学习]js接口继承

js是面向对象语言,但是js又缺乏了面向对象的诸多特性,比如继承,没有接口继承也没有父类继承,因此有时候需要人工来实现继承. 一.首先看下java中面向对象的继承: //定义类鸟类的飞行动作 interface BirdFlyable { public void fly(); } //鸟类 class Bird implements BirdFlyable{ public void fly(){ System.out.println("bird is flying"); } } //蝙

[技术学习]js正则表达式汇总

一.常用正则表达式关键字 ".":任意字符 "*":任意个数 "+":任意个数,至少一个 "?":0-1个 "\d":任意个数数字,至少一个 digit "\w":任意数字字母,下划线 word "\s":任意空白,空格,tab,换行符,至少一个 space \:转义符 []:匹配一些字符 -:例如0-5,从几到几 ^:任意的非字符 \S:所有非空白 {4}:字符出现

我的2015技术学习流水账

我的2015技术学习流水账 2015年马上就要过去了,匆匆忙忙地又是一年.回头总结整理,发现这一年还挺充实的.在正常上班工作之余,学习到了不少新东西,不禁感到很欣慰!一个多月前就开始写,终于赶在2016年来临之前写完了这篇文章-- 关于本文,尽管叫做流水账,但是出于程序员条理性的"强迫症",还是进行系统分类,分类方法参照Thoughtworks技术雷达的Tecniques.Languages & Frameworks.Tools.Platforms,将其中的Tecniques改

js继承的常用方式

写在前面的话:这篇博客不适合对面向对象一无所知的人,如果你连_proto_.prototype...都不是很了解的话,建议还是先去了解一下JavaScript面向对象的基础知识,毕竟胖子不是一口吃成的. 我们都知道面向对象语言的三大特征:继承.封装.多态,但JavaScript不是真正的面向对象,它只是基于面向对象,所以会有自己独特的地方.这里就说说JavaScript的继承是如何实现的. 学习过Java和c++的都知道,它们的继承通过类实现,但JavaScript没有类这个概念,那它通过什么机

更快学习 JS 的 6 个简单思维技巧

当人们尝试学习 JavaScript , 或者其他编程技术的时候,常常会遇到同样的挑战: 有些概念容易混淆,特别是当你学习过其他语言的时候. 很难找到学习的时间(有时候是动力). 一旦当你理解了一些东西的时候,却很容易再一次忘记. 可以使用的工具甚多且经常变化,所以不知道从哪里开始入手. 幸运的是,这些挑战最终都可以被战胜.在这篇文章里,我将介绍 6 个思维技巧来帮你更快的学习 JavaScript ,让你成为一个更快乐更多产的程序员. 1.不要让将来的决定阻止你进步 对于很多学习 JavaSc

Java多线程技术学习笔记(二)

目录: 线程间的通信示例 等待唤醒机制 等待唤醒机制的优化 线程间通信经典问题:多生产者多消费者问题 多生产多消费问题的解决 JDK1.5之后的新加锁方式 多生产多消费问题的新解决办法 sleep和wait的区别 停止线程的方式 守护线程 线程的其他知识点 一.线程间的通信示例 返目录回 多个线程在处理同一资源,任务却不同. 假设有一堆货物,有一辆车把这批货物往仓库里面运,另外一辆车把前一辆车运进仓库的货物往外面运.这里货物就是同一资源,但是两辆车的任务却不同,一个是往里运,一个是往外运. 下面

JS继承——原型的应用

前面我们知道JS是基于对象编程的一种脚本语言,在JS本着一切皆对象的原则,对象之间也涉及到了继承,不过这里的继承与我们以往学习过的继承有所不同,它运用的是对象的原型,来构造一个原型链来实现对超类对象的继承. 1.如何实现对象继承 function Box() { //Box 构造<span style="font-family:Arial;font-size:18px;">,超类对象</span> this.name = 'Lee'; } Desk.protot

【转知乎】如何学习js(http://www.zhihu.com/question/21064817)

首先要说明的是,咱现在不是高手,最多还是一个半桶水,算是入了JS的门. 谈不上经验,都是一些教训. 这个时候有人要说,“靠,你丫半桶水,凭啥教我们”.您先别急着骂,先听我说. 你叫一个大学生去教小学数学,不见得比一个初中生教得好.因为大学生早已经过了那个阶段,都忘记自己怎么走过来的了.而对于初中生,刚好走过那个阶段,对自己怎么走过来的还记忆犹新,或者还有一些自己的总结.比如,很多高手觉得那本犀牛书入门很好,他们觉得太简单了,但以我的经验来看,它不是入门的最好选择. 先说说学js的条件 论条件,咱

java技术学习路线

随着互联网行业的高速发展,编程无疑越来越深入人心.而Java是当前世界非常流行的编程语言之一,代表着很高的薪资和很好的待遇.现在社会也确实有很多人渐渐的对java产生了不小的兴趣,也想在Java这个领域分一份羹,但苦于入不得其门,本文针对Java初学者介绍一下Java的学习方法. 近期对Java这门语言也有了比以前更深刻的认识,学习了Java的一些基本语法,比如数据类型.运算符.程序流程控制.数组,也在逐渐上升到面向对象编程这一概念.而Java核心的核心就是面向对象思想,只要能够掌握好面向对象这