• javascript中的原型详解


     前言

      都知道,原型能够使对象的方法达到复用的目的,而不是每个对象都存在相同方法。

    概念

      在详细了解原型之前,需要明白以下概念:
        prototype:原型,函数自带的属性,也是一个对象;
        constructor:原型对象自带的一个属性,指向宿主原型的宿主方法;
        __proto__:对象的一个属性,指向实例化出该对象的方法的原型。

      例:
        一个方法 A,实例化出一个 a,则此时 a.__proto__ === A.prototype,而 A.prototype.constructor === A

    new 实现

      想要了解原型是如何复用对象的,就得了解一个方法是怎么 new 出对象的,直接看代码:

     1 function MyNew(fn, ...args){
     2     let obj = Object.create(fn.prototype)
     3     let res = fn.apply(obj, args)
     4     return res instanceof Object ? res : obj
     5 }
     6 
     7 function A (name){
     8     this.name = name
     9 }
    10 let a = MyNew(A, "jane")
    11 console.log(a.name)

      上面代码,通过自己实现的 MyNew 成功实例化 A,并成功打印出 jane。
      通过上面代码,可以看出 new 其实就是新创建出一个Object,然后再通过 apply 将新创建的对象(this)绑定到A上,再返回,这样就成功访问 A 的 name 并打印。

      

      下面再给 A 的 prototype 添加一个方法:

    1 function A (name){
    2      this.name = name
    3 }
    4 A.prototype.fn = function(){
    5      console.log(1)  
    6 }
    7 let a = MyNew(A, "jane")
    8 a.fn()

      A 的 实例仍然可以访问 A 上的 prototype 上的方法。再看 MyNew ,这是因为,在创建 obj 的时候,已经将 obj 的 __proto__ 链接在了 A.prototype 上了,这样在调用方法时,在自身对象找不到的情况下,就会往 __proto__ 找,而 __proto__ 又链接在 A.prototype 上,最终在 A.prototype 上找到方法。

      再看下面的方式调用:

    1 a.hello()
    2 
    3 // ------
    4 
    5 a.toString()

      当 a 调用 hello 方法时会报错,而当 a 调用 toString 方法时却可以成功调用。
      这里 hello 在原型上没有找到,属于正常保存,而 toString 是因为在 Object 上找到了,所以没报错。这里容易忽略的一点就是 prototype 也是一个对象,也有 __proto__ 属性,而 prototype 的 __proto__ 则指向 Object.prototype,所以最终在 Object 上找到 toString。

    prototype.constructor

      这个属性( constructor )与 class 中的 constructor 构造不同,并没有什么特殊的地方,甚至可以改掉其值,而唯一性作用可能是获取其宿主原型的宿主方法吧。

    黑话

      本文中提到了宿主原型,宿主方法,为了避免误解,这里说一下它们的意思:
        一个 prototype ,而 prototype 中有 constructor ,而 constructor 中的宿主原型就是指 prototype。
        一个方法 A,A 有 prototype ,而 prototype 的宿主方法就是 A 。

    参考

      https://segmentfault.com/a/1190000022927245

      https://zhuanlan.zhihu.com/p/30012224

    Welcome to my blog!
  • 相关阅读:
    TextField KeyUp事件
    extjs 弹出windowsurl
    coolite TreePanel CheckBox联动
    自动生成储存过程及.net代码(sql2000,sql2005,sql2008)
    ComboBox三级关联
    ext window关闭
    DLL编写教程
    阿里云笔试题
    c/c++复杂声明的理解
    malloc/free与new/delete的区别
  • 原文地址:https://www.cnblogs.com/blogCblog/p/14883948.html
Copyright © 2020-2023  润新知