javascript - 原型(prototype)和对象包装器在 JavaScript 中如何工作?

标签 javascript object prototype

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

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

最佳答案

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

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

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

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 方法。

关于javascript - 原型(prototype)和对象包装器在 JavaScript 中如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46270618/

相关文章:

javascript - Lodash 将数组转换为对象

javascript - 在 JavaScript 中可以声明一个新的子类作为原型(prototype)方法吗?

node.js - Sails Js、Node Js 方法

javascript - 为什么构造函数改变了?

javascript - Bootstrap 图片库始终在页面顶部打开

javascript - 使用 Facebook 登录但仍然收到 : "Unauthenticated access is not supported for this identity pool"

javascript - 插入多个文本分隔符 - javascript

javascript - 将值传递给函数参数 javascript 时遇到问题

JavaScript indexOf() 对于数组中已识别的对象返回 -1

java - 更新 TreeMap 中的对象 (Java)