JavaScript原型 - 请澄清

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript原型 - 请澄清相关的知识,希望对你有一定的参考价值。

有人可以帮我理解原型属性吗?我不明白prototype属性是函数的属性还是函数内部的属性。

假设我们创建了以下构造函数Food。此时,函数Food()具有属性Food.prototype。由于Food是Object的一个实例,因此这意味着Obect.prototype是使用Food()创建的所有对象的prototype属性。

function Food() {}

然后创建另一个构造函数Pizza。 Pizza有Pizza.prototype属性。

function Pizza(toppings) {
    this.toppings = toppings;
}

然后我们通过将Pizza的原型属性设置为Food的实例来使Pizza继承自Food。 Pizza的原型属性现在是Food.prototype,因为Food是披萨的父母。

Pizza.prototype = new Food();

然后我们创建一个Pizza实例

var myPizza = new Pizza("pepperoni");

myPizza还有一个继承自Pizza的原型属性吗?如果是这样,myPizza.prototype == Object.prototype?什么是Obejct.prototype?它是Object()的属性吗?只有函数有原型属性吗? Object.prototype是一个对象吗? Pizza.prototype是否指的是创建Pizza构造函数的整个函数?这个函数本身就是一个对象吗?

function Pizza(toppings) {
    this.toppings = toppings;
}

或者Pizza.prototype只是引用Pizza()范围内的内容?

this.toppings = toppings;

Pizza.toppings是Pizza.prototype的属性吗?但是Pizza.prototype不是Pizza()的属性吗?浇头只是使用Pizza构造函数创建的对象的属性吗?而Pizza.prototype是Pizza构造函数的属性?

目前的原型链如下:

myPizza - > Pizza.prototype - > Food.prototype - > Object.prototype

答案

我不是从问题的答案开始,而是从原型和构造函数的工作方式开始,以避免在尝试用部分理解来解释这些答案时产生混淆。那么,原型回顾:

  • javascript中的每个值,除了nullundefined,都有一个相关的值:它的原型.¹
  • 原型用于查找属性。当你评估x.foo时,你会检查值x是否有自己的属性 - 一个属于它自己的属性 - 名为“foo”。如果是这样,x.foo就是那个属性的价值。如果没有,查找继续在x的原型。
  • 值的原型可以是null,这意味着任何找不到自己的属性的属性查找都会导致undefined
  • 您可以使用Object.getPrototypeOf函数获取值的原型。
  • 您可以使用功能Object.create创建具有特定原型的新对象。

JavaScript中的构造函数具有名为“prototype”的属性。此属性的值不是构造函数的原型;它是使用构造函数创建的值的原型。以您的示例构造函数为例:

function Food() {}

如果运行new Food(),将创建一个新对象,其原型设置为Food.prototypeFood将在this设置为该新对象的情况下执行。换句话说,这个:

// create a new instance of Food
let f = new Food();

意思是这样的:

// create a new object with Food.prototype as its prototype
let f = Object.create(Food.prototype);

// initialize it using the constructor
Food.call(f);

现在,上面总结的属性查找工作方式产生了一个原型链。如果x有一个原型y而且y没有原型,那么x.foo会在这个链上查找:

x -> y -> null
  1. 如果x拥有自己的属性“foo”,则x.foo会评估其值
  2. 如果y拥有自己的属性“foo”,则x.foo会评估其值
  3. 我们已到达null,链的末端,所以x.fooundefined

构造函数的prototype属性的默认值是一个新的Object实例,因此new Food()的原型链如下所示:

f -> Food.prototype -> Object.prototype -> null

并且您可以说值x是构造函数C的一个实例,如果x的原型是C.prototypex的原型不是null并且是C的实例。 (如果xC.prototypex不是C的一个例子。)这就是instanceof算子的工作方式²:

console.log({} instanceof Object);  // true
console.log(Object.prototype instanceof Object);  // false

以上是关于JavaScript原型 - 请澄清的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript构造函数的方法与原型对象

访问 Javascript 对象原型 [重复]

javascript 请记住在更改原型时设置构造函数属性

在javascript中为什么重置后函数的原型也需要重置函数原型构造函数?

澄清我被分配的一些javascript任务[关闭]

请澄清 const 限定符传播