zoukankan      html  css  js  c++  java
  • new操作符的内部运行解析

    在加上new操作符,我们就能完成传统面向对象的class + new的方式创建对象,在Javascript中,我们将这类方式成为Pseudoclassical。

    基于上面的例子,我们执行如下代码

     
    var obj = new Base();
     

    这样代码的结果是什么,我们在Javascript引擎中看到的对象模型是:

    new操作符具体干了什么呢?其实很简单,就干了三件事情。

     
    var obj  = {};
    obj.__proto__ = Base.prototype;
    Base.call(obj);
     

    第一行,我们创建了一个空对象obj
    第二行,我们将这个空对象的__proto__成员指向了Base函数对象prototype成员对象
    第三行,我们将Base函数对象的this指针替换成obj,然后再调用Base函数,于是我们就给obj对象赋值了一个id成员变量,这个成员变量的值是”base”,关于call函数的用法,请参看陈皓《Javascript 面向对象编程》文章

    var cat = new Animal("cat");

    JS引擎执行这句代码时,在内部做了很多工作,用伪代码模拟其工作流程如下:

    复制代码
    new Animal("cat") = {
    
        var obj = {};
    
        obj.__proto__ = Animal.prototype;
    
        var result = Animal.call(obj,"cat");
    
        return typeof result === 'object'? result : obj;
    }

    (1)创建一个空对象obj;

    (2)把obj的__proto__ 指向Animal的原型对象prototype,此时便建立了obj对象的原型链:obj->Animal.prototype->Object.prototype->null

          【如果你不了解JS原型链,请先阅读:JS原型和原型链

    (3)在obj对象的执行环境调用Animal函数并传递参数“cat”。 相当于var result = obj.Animal("cat")。

           当这句执行完之后,obj便产生了属性name并赋值为"cat"。【关于JS中call的用法请阅读:JS的call和apply

    (4)考察第3步返回的返回值,如果无返回值或者返回一个非对象值,则将obj返回作为新对象;否则会将返回值作为新对象返回。

    一般情况下,函数对象在产生时会内置name属性并将函数名作为赋值(仅函数对象)。

  • 相关阅读:
    LeetCode Flatten Binary Tree to Linked List
    LeetCode Longest Common Prefix
    LeetCode Trapping Rain Water
    LeetCode Add Binary
    LeetCode Subsets
    LeetCode Palindrome Number
    LeetCode Count and Say
    LeetCode Valid Parentheses
    LeetCode Length of Last Word
    LeetCode Minimum Depth of Binary Tree
  • 原文地址:https://www.cnblogs.com/jiangtian/p/6343733.html
Copyright © 2011-2022 走看看