javascript中的继承

欢迎访问我的博客,祝码农同胞们早日走上人生巅峰,迎娶白富美~~~

面向对象的基本特征有:封闭、继承、多态

在JavaScript中实现继承的方法:

  1. 原型链(prototype chaining)
  2. call()、apply()
  3. 混合方式(prototype和call()/apply()结合)
  4. 对象冒充

javascript对象冒充实现继承

本质上就是改变this指向

对象冒充

原理:

构造函数使用this关键字给所有属性和方法赋值.因为构造函数只是一个函数,所以可使ClassA的构造方法称为ClassB的方法,然后调用它.

ClassB就会收到ClassA的构造方法中定义的属性和方法.

例子:

        function ClassA(name){
            this.name=name;
            this.getName=function(){
                return this.name;
            }
        }
        
        function ClassB(name,password){
            this.ClassA=ClassA;
            this.ClassA(name);
            delete this.ClassA;
            
            this.password=password;
            this.getPassword=function(){
                return this.password;
            }
        }
        
        var b =new ClassB('wwww','1123');
        document.write(b.getName());

经过调试,我们可以看到: 变量b中已经包含了ClassA中定义的方法.

对象冒充

代码理解:

在ClassB中,this.ClassA(name)等价于以下代码:

this.name=name;
     this.getName=function(){
         return this.name;
     }

所以将ClassA函数中的代码复制过来,即:ClassB中的代码如下:

        function ClassB(name,password){
            this.ClassA=ClassA;
            
            this.name=name;
            this.getName=function(){
                return this.name;
            }
            
            delete this.ClassA;
            
            this.password=password;
            this.getPassword=function(){
                return this.password;
            }
        }

然后通过delete this.ClassA之后,ClassB中的实际代码如下:

        function ClassB(name,password){
            this.name=name;
            this.getName=function(){
                return this.name;
            }
            
            this.password=password;
            this.getPassword=function(){
                return this.password;
            }
        }

从而实现了对象冒充.

注意:

对象冒充可以支持多重继承,也就是说一个类可以继承多个类.例子如下:

        function ClassC(){
            this.ClassX=ClassX;
            this.ClassX();
            delete this.ClassX;
            
            this.ClassY=ClassY;
            this.ClassY();
            delete this.ClassY;
        }

这样就ClassC就实现了继承自ClassX,ClassY.但此处存在一个弊端:

若ClassX和ClassY中存在两个同名的变量或方法,则ClassY会覆盖ClassX中的变量或方法.

此外:

我们还可以通过call()和apply()方法实现对象冒充.

call方法

它的第一个参数用做this的对象,其他参数都直接传递给函数自身.我们来看下面这个小例子:

        function ShowColor(param1,param2){
            this.getColor=function(){
                document.write(this.color+"<br/>Two Params : "+param1+" ; "+param2);
            }
        }
        
        var obj = new Object;
        obj.color='Red';
        ShowColor.call(obj,"pm1",'pm2');
        
        obj.getColor();

运行此段代码后,我们发现页面上显示为:

call

解释:

ShowColor方法是在对象外定义的,调用call时,它将第一个参数,也就是将ClassA的this指向了obj,将后面的参数"pm1"传递给了param1,'pm2'传递给了param2.

        var obj = new Object;
        obj.color='Red';
        ShowColor.call(obj,"pm1",'pm2');

也就实现了以下效果:

我们将上面代码中的obj.color='Red'给注释起来,再运行代码,结果如下:

call_undefine

原因是obj并没有color属性,而obj.getColor()方法中需要this.color,即obj.color,所以会出现undefined的结果.

我们再来看如何利用call来实现对象冒充,继续以刚才的ClassA,ClassB为例:

        function ClassA(name){
            this.name=name;
            this.getName=function(){
                return this.name;
            }            
        }
        
        function ClassB(name,password){
            //this.ClassA=ClassA;
            //this.ClassA(name);
            //delete this.ClassA;
            ClassA.call(this,name);
            
            this.password=password;
            this.getPassword=function(){
                return this.password;
            }
        }
        var b = new ClassB('www','111');
        b.getPassword();

调试效果:

[图片上传失败...(image-385558-1548520349105)]

解释:

此处的ClassA.call(this,name); 即将ClassA的this指向了ClassB的this.从而实现了对象冒充.

apply方法

apply方法有两个参数,用作this的对象和要传传递给函数的参数的数组.

例子:

        function ShowColor(param1,param2){
            this.getColor=function(){
                document.write(this.color+"<br/>Two Params : "+param1+" ; "+param2);
            }
        }
        
        var obj = new Object;
        obj.color='Red';
        ShowColor.apply(obj,new Array("pm1",'pm2'));
        
        obj.getColor();

此方法可以被用于对象冒充:

        function ClassA(name){
            this.name=name;
            this.getName=function(){
                return this.name;
            }            
        }
        
        function ClassB(name,password){
            //this.ClassA=ClassA;
            //this.ClassA(name);
            //delete this.ClassA;
            ClassA.apply(this,new Array(name));
            
            this.password=password;
            this.getPassword=function(){
                return this.password;
            }
        }
        
        var b = new ClassB('www','111');
        b.getPassword();

调试效果:

apply_result

原型继承

Javascript对象的创建和继承使用了一套特别的模式,称作原型式继承.

原理是:对象的构造函数可以从其他对象中继承方法,它创建出一个原型对象后,所有其他的新对象都可以基于这个原型对象来构建.

原型本身并不会从其他原型或者构造函数中继承属性,而属性都是从实际对象那里继承过来的.

例1:

        function Person(name){
            this.name=name;
        }
        
        Person.prototype.GetName=function(){
            return this.name;
        }
        
        function User(name,password){
            this.name = name;
            this.password = password;
        }
        
        User.prototype = new Person();
        User.prototype.GetPassword=function(){
            return this.password;
        }

解释:

User.prototype = new Person();这句话如何理解呢?User是对User对象构造函数的引用,new Person()使用person构造函数创建了一个Person对象,然后把Person对象的原型置为这个操作的结果.也就是说,当每次new User()时,得到的新User对象都会带有Person对象的所有方法

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349

推荐阅读更多精彩内容

  • 基于这篇文章的一些名称约定: 上面的约定应该是比较合理的,如果难以理解,可以查看黯羽轻扬:JS学习笔记2_面向对象...
    一直玩编程阅读 524评论 1 7
  • 一、继承的概念 继承是所有面向对象语言中最重要的一个特征。而执行环境也是JS最为重要的一个概念。执行环境定义了变量...
    vinterx阅读 301评论 0 0
  • ECMAScript关键字 delete do else finally function in instance...
    doudou2阅读 716评论 0 0
  • 很多语言中都有继承的概念,继承这种东西为什么会出现? 简而言之,继承之所以出现,就是为了减少重复无用功。好比爸爸有...
    小丸子啦啦啦呀阅读 389评论 2 0
  • 是春雨过后充满清新气息的草地 是炎炎夏日海边吹来清凉的海风 是天气微凉及时披上的温暖外套 是皑皑白雪环绕里静静沐浴...
    戏精闪闪阅读 127评论 0 0