• js继承中,原型属性的继承探究


    最近研究了js的继承,看了幻天芒的文章http://www.cnblogs.com/humin/p/4556820.html#3947420,明白了最好是使用apply或call方法来实现继承。

    已知,call可以将function里的属性(所谓构造属性)赋给子类;但是对于call能不能将function的prototype内容(所谓的原型属性)一同复制,有疑惑,实验之后发现是不行的。看下面的代码:

    g()是f()的原型中的方法。

    c是f子类e的一个实例,ff是f的一个实例。

    ff.g()系统不报错,正常运行,c.g()系统是报错不识别,不认为其是一个函数。 

    结论:e没有继承父类f的原型属性。

    function f(){ 
    this.a ="a"; 
    this.b = function(){ 
    console.log("b"); 
    }
    /*
    this.g = function(){
    console.log("this is g in f()."); 
    }
    */
    } 
    f.prototype.g = function(){
    console.log("this is g in prototype."); 
    }
    
    function e(){ 
    f.call(this); 
    } 
    var c = new e(); 
    console.log(c.a); //弹出a 
    c.b(); //弹出b
    
    var ff = new f();
    ff.g();//this is g in prototype.
    c.g();//c.g is not a function
    

      

    如果要实现对f的完全继承,还需要复制其原型链中的内容。参考以下代码:

    function f(){ 
    this.a ="a"; 
    this.b = function(){ 
    console.log("b"); 
    }
    } 
    f.prototype.g = function(){
    console.log("this is g in prototype."); 
    }
    
    function e(){ 
    f.call(this); 
    //f.prototype.call(this);
    }
    
    (
    function(){
    var Super = function(){};
    Super.prototype = f.prototype;
    e.prototype = new Super();
    }
    )();
    
    e.prototype.constructor = e; //重新修复下构造函数
    var c = new e(); 
    console.log(c.a); //弹出a 
    c.b(); //弹出b
    
    var ff = new f();
    ff.g();//this is g in prototype
    c.g();//this is g in prototype

    总结,f.call(this);只能将f的实例属性赋给e,原型属性需要使用别的方法复制过去。

    另外,我又在chrome下最后使用代码:

    console.log(c);
    

     打印了一下实例c。看到如下内容:

     a,b都好理解。a是父类f的一个实例属性,b是父类f的一个实例方法。e都继承了下来。可是问题来了:

    __proto__是什么呢?

    e继承的父类f的原型方法g()去哪里了呢?

    回答以上问题,先看一看js对于__proto__的定义和解释:

    在JS里,万物皆对象。方法(Function)是对象,方法的原型(Function.prototype)是对象。因此,它们都会具有对象共有的特点。
    即:对象具有属性__proto__,可称为隐式原型,一个对象的隐式原型指向构造该对象的构造函数的原型,这也保证了实例能够访问在构造函数原型中定义的属性和方法
    来源:https://www.zhihu.com/question/34183746/answer/58155878

     现在我们来分析,实例c是e对象生成的,e的构造函数的原型(即e.prototype)是f。再点开来看:

    __proto__.constructor = e(); 这个不就是我们设置的吗----》e.prototype.constructor = e;  __proto__.__proto__.g  = function 这个是构造函数原型的构造函数的原型,即f的构造函数原型,即f的原型链。g不就是f原型链中的方法吗。 所以,e继承的父类f的原型方法g()在这里。原来,使用c.g()时候,程序会一直沿着__proto__往前面的原型找。

    作者:Leven
    本博客主要记录个人工作和学习中的一些总结,经验和感悟。欢迎转载和评论,转载请给出原文链接。
    您也可以通过邮箱联系我:leven_developer#outlook.com
    如果文章对您有所帮助,您可以给我一点打赏,会让我更有动力做所从事的事情,非常感谢。
  • 相关阅读:
    Pizza Pie Charts – 基于 Snap SVG 框架的响应式饼图
    超好玩!10款神奇的字符图案 & 词汇云生成工具
    『摄影欣赏』15幅迷人的来自世界各地的婴儿照片【组图】
    CSS 魔法系列:纯 CSS 绘制图形(各种形状的钻石)
    【特别推荐】10款唯美浪漫的婚礼 & 结婚纪念网站模板
    25款创新的 PSD 格式搜索框设计素材【免费下载】
    时尚前沿:15个创意的 3D 字体设计艺术作品欣赏
    Resumable.js – 基于 HTML5 File API 的文件上传
    经典设计:17个最有效的学习着陆页设计的例子
    图标集锦:10套免费的社交媒体 & 社交网站图标
  • 原文地址:https://www.cnblogs.com/Andres/p/8793542.html
Copyright © 2020-2023  润新知