【问题标题】:How does prototypes and object wrappers work in JavaScript?原型和对象包装器如何在 JavaScript 中工作?
【发布时间】:2017-09-18 02:02:00
【问题描述】:

我用几句话写下了我学到的东西,以真正理解原型和对象包装器的工作原理。如果我错了,请纠正我,如果我遗漏了其他详细信息,请告诉我。

JavaScript 使用 prototype 来查找对象的方法和属性。例如,如果您创建一个字符串"Hello",它是一个原始字符串值,并尝试在其上应用split() 方法("Hello".split()),字符串值被强制转换为一个字符串对象,因此我们可以应用split() 方法.此 String 对象由String.prototype.constructor 创建。创建之后,JavaScript 会在原型对象中查找 split() 方法。应用方法并返回值后,不再需要 String 对象,因此献祭给垃圾收集之神。

【问题讨论】:

    标签: javascript object prototype


    【解决方案1】:

    您基本上是正确的,尽管堆栈空间和继承是两个不同的问题,并且在像 js 这样的高级脚本语言中,垃圾收集究竟是如何工作的可能是不确定的。确实,单个代码行的中间值会在该行完成后被销毁。

    此外,String.prototype.constructor 将与 String 本身相同。 String 的任何“实例”都会收到一个指向String.prototype.__proto__ 引用,从而创建一个继承链。如果发现对象属性不是对象x 本身,JavaScript 会自动检查由x.__proto__ 引用的对象,然后是x.__proto__.__proto__,一直到 — 在大多数情况下 — Object.prototype

    请记住,__proto__ 在 JavaScript 解释器之间的实现方式不同,不应手动操作。很高兴知道存在这样的引用来解释原型魔法,但在任何情况下都不应直接更改对象的 __proto__ 引用。相反,您应该通过new 运算符或Object.create 创建一个类的实例。 JavaScript 中完整的超类/子类关系如下所示:

    function Animal( name, weight ){
        this.name = name, this.weight = weight;
        this.alive = true;
        this.hungry = true;
    }
    
    // At this point you could put in Animal.prototype = Object.create(Object.prototype); but JavaScript will set it automatically, so it’s unnecessary
    
    Animal.prototype.kill = function(){
        this.alive = false;
    }
    
    Animal.prototype.feed = function(){
        this.hungry = false;
    }
    
    function Cat(name, weight){
        Animal.call(this, name, weight);
        this.lives = 9;
    }
    
    
    // Sometimes people instance a new parent like
    // Cat.prototype = new Animal('doesntmatter', 420);
    // The result is the same except that using Object.create saves the overhead
    // of running a full constructor for an object that doesn’t need it
    Cat.prototype = Object.create(Animal.prototype);
    
    Cat.prototype.kill = function(){
        this.lives--;
        if(this.lives <= 0) this.alive = false;
    };
    
    
    var a = new Animal();
    var c = new Cat();
    
    /* a.feed and b.feed now reference the same function object,
    but c.kill has been overridden since its prototype `__proto__` chain first 
    visits Cat.prototype, then Animal.prototype, then Object.prototype. */
    

    最后,ES6 引入了一个 class 关键字,这是该系统的语法糖,并将构造函数抽象为 init 方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-01
      • 2015-08-12
      • 2021-11-02
      • 2019-10-17
      相关资源
      最近更新 更多