再和“面向对象”谈恋爱 - super(六)

上一篇文章里介绍了继承,那其中说过一个很关键的东西想要继承子类里里必需先调用一个super方法。而super的作用绝对是价值连城!同时super的作用还有多种,并且跟你的使用环境有关系。

1、当作函数使用

super被当作函数使用,这种情况是最普遍的,上一篇文章里已经使用过。它有以下几种作用:

  1. super作为函数调用时,代表父类的构造函数
  2. 调用super后,this会被改成子类
  3. 只能用在构造函数里,用在其它地方报错
{
    class Father{
        constructor(){
            console.log(new.target.name);
        }
    }
    class Son extends Father{
        constructor(){
            super();
            this.a=10;  //这里的this指向,Son的实例
        }
        method(){
            //super()   报错,只能用在constructor里
        }
    }
    new Father();   //Father(new.target返回Father类)
    new Son();      //Son(new.target返回Son子类)
    console.log(new Son().a);   //10 this指向被修改成了子类的实例
}

子类里面并没有写console.log,但是发现生成子类实例后,控制台里有输出。说明:super其实相当于执行了父级的constructor方法。同时弹出的结果是指向了子类,又说明虽然调用的是父类的构造函数,但是调用完后会指向子类,this指向也被改成了子类的实例。其实supe的作用相当于执行Father.prototype.constructor.call(this);

2、当作对象使用

super也可以被当作对象使用,被当作对象使用的时候情况有些复杂,跟上面是完全不一样的,同时又按使用环境分为了两种情况。

  1. 在普通方法中,指向父类的原型对象
* 只能调用原型里的东西
* 如果调用的是方法,那方法内部this指向子类实例
* 如果用super去添加属性的话,super就是this(实例)
  1. 在私有方法中,指向父类,而不是父类的原型
* 如果调用的是方法,那方法内部this指向子类而不是子类实例

在普通方法中使用

此时切记用super去获取跟设置时的指向完全不一样

{
    class Father{
        constructor(){
            this.a='父类实例的a';
            this.b='父类实例的b';
        }
        showB(){
            console.log(`这是父类身上的共享方法,并且会弹出${this.b}`);
        }
        static showB(){ //私有方法可以与上面的方法重名
            console.log(`这是父类身上的私有方法,并且会弹出${this.b}`);
        }
    }
    Father.prototype.a='父类原型的a';   //在原型身上的添加一个属性a
    
    class Son extends Father{
        constructor(){
            super();    //这里的super是个方法,作用为引入父类的构造函数(当作函数使用)
            this.b='子类实例的b';
            
            //此处声明:请按注释标的序号顺序执行代码
            
            //
            /*
             *  3、super设置属性
             *      1、用super设置属性的话,super就代表当前环境的this。而当前环境为子类的constructor,所以此时的super代表的就是子类的实例对象
             *      2、此时下面的showB()方法弹出的内容为"这是父类身上的共享方法,并且会弹出super就是this"是因为,如果super为this的话,那就与上面那段代码重复了,后面覆盖前面
             *
             */
            super.b='super就是this';
            
            
            /*
             *  4、super获取属性
             *      1、此时super的作用是获取属性,它依然指向父类的原型对象所以下面这句话相当于console.log(Father.prototype.b);所以结果为undefined。虽然在上面定义了super.b那也不会改变super的指向
             */
            console.log(super.b);     //undefined
            
            
            /*
             *  1、这里的super是一个对象,因为constructor是个普通对象
             *      1、super指向父类的原型对象,调用的是Father的共享方法showB()
             *      2、showB方法里的this指向子类的实例,取的是Father的constructor里定义的b
             */
            super.showB();  //这是父类身上的共享方法,并且会弹出子类实例的b
            
            
            //2、super获取属性
            console.log(super.a);   //父类原型的a   再次验证只能调用原型上的东西。原型上与constructor里都有个a,但是调的是原型上的
        }
    }
    Son.b='子类的私有属性b';
    new Son();
}

在私有方法中使用

此时切记用super的用法与在普通方法中的用法完全相反

{
    class Father{
        constructor(){
            this.b='父类实例的b';
        }
        showB(){
            console.log(`这是父类身上的共享方法,并且会弹出${this.b}`);
        }
        static showB(){ //这是个私有方法,与上面的方法重名是可以的
            console.log(`这是父类身上的私有方法,并且会弹出${this.b}`);
        }
    }
    Father.prototype.b='父类原型的b';   //在原型身上的添加一个属性b
    
    class Son extends Father{
        constructor(){
            super();
            this.b='子类实例的b';
        }
        
        /*
         *  1、这里的super是在私有方法里调用,所以指向父类,调用的是Father里定义的static showB方法
         *  2、此方法里的this指向被改成了子类,弹出的b是子类的私有属性b
         */
        static log(){
            super.showB();
        }
    }
    Son.b='子类的私有属性b';
    Son.log();  //这是子类身上的私有方法,并且会弹出子类的私有属性b
}

忠告:要明确指定supe的类型

super在用的时候必需指定它的类型,不然不清不楚的去用,浏览器会给你报错!

{
    class Father{};
    class Son extends Father{
        constructor(){
            super();    //这个是作为函数
            //console.log(super);   //报错  那这个super它是个什么呢?它自己矛盾了,浏览器迷茫了~
            console.log(super.a);   //这个是作为对象
        }
    }
}

下一篇,实战!硬邦邦的干货

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

推荐阅读更多精彩内容

  • 这是16年5月份编辑的一份比较杂乱适合自己观看的学习记录文档,今天18年5月份再次想写文章,发现简书还为我保存起的...
    Jenaral阅读 2,739评论 2 9
  • v 把 v 海关监管机构吧和 v 哈哈 vv 宝宝 v 你吧
    雪零人参阅读 162评论 0 0
  • 凌君初来这个城市的时候,是奔着她亲三舅来的。所有的亲戚中,就他家过的好,开了家大饭店,在郊区住着三层别墅。 其他的...
    不回首2020阅读 226评论 0 0
  • 面朝大海,春暖花开,到底是自由的向往还是简单的渴望阳光。那个困顿的岁月中,海子一个才华横溢的诗人,面对生活,却走不...
    90后青衣阅读 1,852评论 23 16
  • 眼神像云一样失落 在你叹息的时候 我去做一个长长的梦 梦见给孩子上课 在操场上打太极 读诗集 春风卷着柔情 低低地...
    宇斯阅读 325评论 0 2