js的prototype的向下扩展和__proto__的向上扩展

时间:2022-02-11 03:22:23

     在es5之前js中是没有显式的继承,那也就没有所谓显式的多态,那是不是就无法扩展对象的方法,很显然不是。

 我们先从File这个类对象看起,这是一个上传文件的测试代码。

    
 
 
 
 
<input type="file" name="TEST_FILE" id="test_file"> <script> var _file=document.getElementById('test_file');
 var file; _file.addEventListener('change',function(){ file=_file.files[0]; console.log(file); },false) </script>

 
       打印的结果如下:
  1. File={
    1. lastModified:1468122486200
    2. lastModifiedDate:Sun Jul 10 2016 11:48:06 GMT+0800 (中国标准时间)
    3. name:"OpenCV入门教程.pdf"
    4. size:1976138
    5. type:"application/pdf"
    6. webkitRelativePath:""
    7. __proto__:File
    8. },
    9. 对象初始化之后会带有File()这个构造函数内部this的属性和方法,
    10. 看最后一个属性__proto__,比较形象的指向了这个对象的构造函数的原型,
    11. 可以打印file.__proto__===File.prototype // true,继续看这个原型链指向的原型。
    12. File.prototype=
    13. {
      1. constructor:File()
      2. lastModified:(...)
      3. get lastModified:()
      4. lastModifiedDate:(...)
      5. get lastModifiedDate:()
      6. name:(...)
      7. get name:()
      8. size:(...)
      9. type:(...)
      10. webkitRelativePath:(...)
      11. get webkitRelativePath:()
      12. Symbol(Symbol.toStringTag):"File"
      13. __proto__:Blob
    14. 这是其实可以看到File.prototype非常像一个类,
    15. 有构造函数,有成员函数,有成员变量,这里又看到一个__proto__:Blob
    16. Blob.prototype={

      1. constructor:Blob()
      2. size:(...)
      3. get size:()
      4. slice:slice()
      5. type:(...)
      6. get type:()
      7. Symbol(Symbol.toStringTag):"Blob"
      8. __proto__:Object
      9. }
      10. 继续测试 file._proto_.__proto__===File.prototype.__proto__===Blob.prototype// true 

      11. 会发现 File.prototype和Blob.prototype这两个类通过__proto__完成了继承,
      12. 这个关键词就像extends 一样了。
      13. 接下来我们通过一段代码来验证这个继承:
         function Person() { } Person.prototype= { say:function() { console.log("我是一个人"); } } function Children() { } Children.prototype= { play:function() { console.log("我会玩"); } } Children.prototype.__proto__=Person.prototype; var xiaoming=new Children(); xiaoming.say(); xiaoming.play();
        构造函数内部的对象的属性和方法可以通过apply继承,
      14. 下次可以看看用apply继承和调用其他对象的方法。