zoukankan      html  css  js  c++  java
  • JavaScript对象模型概念

    1.对象的概念

      JavaScript只有函数对象才有类的概念,因此创建一个对象,必须使用函数对象。(ES6中可以直接声明一个class,实质上也是一个函数对象)。

    函数对象的内部有[[Construct]]方法[[Call]]方法。[[Construct]]用于构造对象,[[Call]]用于函数调用。当使用 new 操作符的时候才会触发[[Construct]]

    逻辑。var obj = new Object();调用Object()构造函数创建实例对象,var obj = {};是有js引擎直接生成的实例对象,不调用[[Construct]]逻辑,效率更高。

    2.对象创建过程

      var obj = new  Fn(args);用户自定义构造函数实例化对象。

    new Fn(args):使用new操作符时触发Fn 的[[Construct]]逻辑,创建对象的步骤如下:

    1.  创建一个build-in object对象obj(实例对象);

       (并完成内部必要的初始化,它的[[Class]]、[[Extensible]]、[[Prototype]]等属性应当为null或者内部初始化值。)

    2.  设置obj的内部属性[[class]]为"Function",或者其它本地类型,例如:"Number"、"String"、"Boolean"等。这是由构造函数的类型决定的。

    3.  设置obj的内部属性[[Extensible]]为 true。

    4.  如果Fn.prototype是object引用对象类型,则将obj的内部[[Prototype]]设置为Fn.prototype,否则obj的[[Prototype]]将为其初始化值(即Object.prototype)

      备注:重写原型链导致实例对象隐式原型指向问题(实例对象隐式原型会初始化为Object.prototype)

    5.  将obj作为this,使用args参数调用Fn的内部[[Call]]方法。(this.[[Call]](args))

      5.1 创建内部[[Call]]方法的当前执行环境(当前执行环境压入执行环境栈)

        (函数体内function定义的方法的[[Scope]]静态作用域复制到[[Call]]的作用域链,在作用域链的前端添加[[Call]]的活动对象;this引用obj)

      5.2 调用Fn的函数体

      5.3 销毁当前的执行环境(当前执行环境弹出执行环境栈)

      5.4 返回Fn函数体的返回值,如果Fn的函数体没有返回值则返回undefined

    6. 如果返回值是object引用对象类型,则返回这个值;否则(返回值是基本类型)则返回obj

       函数类型对象的创建会把prototype属性的[[Prototype]]设置为Object.prototype,这个过程就是按照上边步骤走一遍,这样默认情况下我们创建自定义函数的实例对象时,它们的Prototype链终将指向Object.prototype。

     

    注意步骤4中, prototype指Fn对象显示的prototype属性,而[[Prototype]]则代表对象内部隐式Prototype属性。

      实例对象Prototype链的是内部隐式的[[Prototype]](原型链),而并非对象显示的prototype属性。显示的prototype只有在函数对象上才有意义,从上面的创建过程可以看到,函数的prototype被赋给实例对象隐式[[Prototype]]属性,这样根据Prototype规则,实例对象和函数的prototype对象之间才存在属性、方法的继承/共享关系。

    3.JavaScript对象模型

    注释: 红色虚线表示隐式的原型链

       

    Prototype链的补充说明:
      1.  Object.prototype是整个链的终结点,它的内部[[Prototype]]为null。
      2.  所有函数的[[prototype]]链都指向Function.prototype。


      Function的Prototype链指向Function.prototype,这是规范要求的,因为设计者将Function设计为具有自举性。Function的Prototype链这样设计之后,Function.constructor==Function, Function instanceOf Function都为true。另外Function已经是最顶层的构造器,但Function本身也是一个函数对象,它必然是由某个东西创建出来的,这样自举在语义上合情合理。
    Function.prototype的[[prototype]]链指向Object.prototype,这也是规范强制要求的。首先Function.prototype是Function的一个实例对象(typeof

    Function.prototype可以知道它是一个Function,instanceOf无法通过测试,因为Prototype链在内部被额外设置了),所以按照Prototype的规则,Function.prototype的prototype值应当为Function.prototype这个对象,即它的Prototype链指向自己本身。这样一方面在Prototype链上造成一个死循环,另一方面它本身成为了一个终结点,结果就是所有函数对象将不是派生自Object了。加上这个强制要求之后,Prototype链只有唯一的一个终结点。


  • 相关阅读:
    设计模式C++描述----06.适配器(Adapter)模式
    设计模式C++描述----05.职责链(Chain of Responsibility)模式
    设计模式C++描述----04.观察者(Observer)模式
    设计模式C++描述----03.工厂(Factory)模式
    设计模式的几种原则
    设计模式C++描述----02.模板(Template)模式
    常用 UML 类图
    前端插件之Bootstrap Switch 选择框开关控制
    Django处理流程
    Django之logging日志
  • 原文地址:https://www.cnblogs.com/windcat/p/11173118.html
Copyright © 2011-2022 走看看