JavaScript基础教程 圣杯模式详解
沉沙 2018-08-08 来源 : 阅读 968 评论 0

摘要:本篇教程介绍了JavaScript基础教程 圣杯模式详解,希望阅读本篇文章以后大家有所收获,帮助大家对JavaScript的理解更加深入。

本篇教程介绍了JavaScript基础教程 圣杯模式详解,希望阅读本篇文章以后大家有所收获,帮助大家对JavaScript的理解更加深入。

<

圣杯模式是Javascript中用来实现继承的一种方法,它的简单形式如下所示
<script>

    function Father(){}
    function Son(){}
    Father.prototype.lastName='Jack';

    //圣杯模式
    function inherit(Target,Origin){
        function F(){};
        F.prototype=Origin.prototype;
        Target.prototype=new F();
    }

    inherit(Son,Father);
    var son=new Son();
    var father=new Father(); 

    Son.prototype.sex='male';
    console.log(son.lastName);//Jack
    console.log(son.sex);//male
    console.log(father.sex);//undefined

</script>

这种圣杯模式的本质在于,中间生成了一个对象,起到了隔离的作用,今后为Son.prototype添加属性时,全部都会加在这个对象里面,所以不会对父级产生影响。
而向上查找是沿着__proto__查找,可以顺利查找到父级的属性,实现继承。
下面来具体分析是如何进行继承的
首先inherit 函数中定义了一个function F ,F用来充当中间层的函数。
之后F.prototype=Origin.prototype; 这一步表示,让F和Father的prototype指向同一地址,即Father.prototype。
下一步Target.prototype=new F(); 表示,通过函数F生成一个对象(这里把这个对象成为objF),让Son函数的prototype指向这个对象objF,到这一步实际上就已经实现了继承。
下方代码中,生成了son和father对象之后,对函数Son的prototype增加了一个sex属性,而Son函数的prototype是指向对象objF的,因此这个sex属性会加到objF之上,因此下方打印son.sex时就会出现male。
而对于son.lastName而言,首先查找Son函数内部是否有lastName属性,很明显没有。
因此就沿着__proto__(即原型链)往上找, 即在函数F中找是否存在该属性。
之前提到了F和Father的prototype都是指向Father.prototype的,而在Father.prototype中存在该属性,因此son.lastName的打印结果为Jack。
最后,由于有中间层F的存在,因此Father的prototype自始至终都没有受到影响,所以father.sex的打印结果为undefined。
一般在使用圣杯模式时还会加上另外两句话

Target.prototype.constructor=Target;
//由于Target.prototype指向的是objF,没有constructor这一属性,沿着__proto__向上查找,发现constructor指向的是Father,因此这里可以进行归位,让它的constructor重新指向它自己
Target.prototype.uber=Origin.prototype;
//uber是超类的意思,这里主要用来储存这个目标到底继承自谁,可写可不写


此外,还有另外一种写法,利用闭包将F作为一个私有化变量,完整代码如下:
<script>
//方法1
    function Father(){}
    function Son(){}
    Father.prototype.lastName='Jack';

    function inherit(Target,Origin){
        function F(){};
        F.prototype=Origin.prototype;
        Target.prototype=new F();
        Target.prototype.constructor=Target;
        Target.prototype.uber=Origin.prototype;
    }

    inherit(Son,Father);
    var son=new Son();
    var father=new Father(); 
    Son.prototype.sex='male';

    console.log(son.lastName);//Jack
    console.log(son.sex);//male
    console.log(father.sex);//undefined


//方法2,利用闭包将F作为一个私有化变量
    var inherit=(function(){
        var F=function F(){};
        return function(){
            F.prototype=Origin.prototype;
            Target.prototype=new F();
            Target.prototype.constructor=Target;
            Target.prototype.uber=Origin.prototype;
        }
    })();

</script>
   

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标WEB前端JavaScript频道!

本文由 @沉沙 发布于职坐标。未经许可,禁止转载。
喜欢 | 1 不喜欢 | 0
看完这篇文章有何感觉?已经有1人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程