javascript - 我们是否应该在 ES6 类的原型(prototype)中包含方法以提高性能?

标签 javascript class inheritance ecmascript-6 prototype

因此,当我了解更多关于 JS 中的原型(prototype)继承时,我在 MDN 中阅读了以下内容文章(阅读此链接上方的行)

Note that when we are calling our constructor function, we are defining greeting() every time, which isn't ideal. To avoid this, we can define functions on the prototype instead, which we will look at later.

建议的想法是在函数上添加属性,在原型(prototype)上添加方法(阅读here)

Person.prototype.farewell = function() {
  alert(this.name.first + ' has left the building. Bye for now!');
};

我以这种方式在多个地方阅读

  • 对象创建速度更快,因为并不是为每个对象创建都创建告别。这是因为它被创建一次并附加到原型(prototype),并且所有对象链接原型(prototype)

  • 原型(prototype)链上查找方法,因此每个对象都链接到原型(prototype)上的相同方法。

现在是 ES6 类。我有以下代码

class Person {
    constructor(first, last, age, gender, interests) {
        this.name = {
            first: first,
            last: last
        };
        this.age = age;
        this.gender = gender;
        this.interests = interests;
    }

    greeting () {
        console.log("Hi! I am", this.name.first);
    }

    farewell () {
        console.log(this.name.first, "has left the building. Bye for now!");
    }
}

似乎通过这种方法,greetingfarewell 将再次创建(遵循与函数相同的逻辑,因为 class 是一种语法糖)

所以,我将类(class)更改为

class Person {
    constructor(first, last, age, gender, interests) {
        this.name = {
            first: first,
            last: last
        };
        this.age = age;
        this.gender = gender;
        this.interests = interests;
    }
}

Person.prototype.greeting = function () {
    console.log("Hi! I am", this.name.first);
}

Person.prototype.farewell = function () {
    console.log(this.name.first, "has left the building. Bye for now!");
}

问题
1.后一种方式(在ES6类中的prototype上添加方法)是推荐的方式吗?
2. class 和传统 new Function 创建新对象的逻辑是否一致? 复制原型(prototype)上的方法

如果我还遗漏了什么,请告诉我

谢谢

<小时/>

更新

经过几个回答后,我重试了我的示例并确认了答案。我的代码看起来像

class Phone {
  constructor(company, name, color, price) {
    this.company = company;
    this.name = name;
    this.color = color;
    this.price = price;
  }

  print() {
    console.log(this.company, this.name, this.color, this.price);
  }
}

class Apple extends Phone {
    constructor(name, color, price) {
        super("Apple", name, color, price);
        this.companyWork = "ClosedSource";
    }
}

let iPhone11 = new Apple("iPhone11", "black", 900);
iPhone11.print()

运行此代码后,我可以确认 print()Phone.prototype
上可用 enter image description here

最佳答案

正如您已经发现的,定义将方法放在原型(prototype)上。您要求提供引用,因此您可以运行以下一些代码来亲自查看:

class Person {
    constructor(first, last, age, gender, interests) {
        this.name = {
            first: first,
            last: last
        };
        this.age = age;
        this.gender = gender;
        this.interests = interests;
    }

    greeting () {
        console.log("Hi! I am", this.name.first);
    }

    farewell () {
        console.log(this.name.first, "has left the building. Bye for now!");
    }
}

let p = new Person("Jack", "Beanstalk", 201, "giant", ["crushing things", "stomping things"]);

console.log("Person", Object.getOwnPropertyNames(Person));

console.log("p", Object.getOwnPropertyNames(p));

let p_prototype = Object.getPrototypeOf(p);

console.log("p_prototype === Person.prototype is ", p_prototype === Person.prototype);

console.log("Person.prototype", Object.getOwnPropertyNames(Person.prototype));

生成此输出:

Person [ 'length', 'prototype', 'name' ]
p [ 'name', 'age', 'gender', 'interests' ]
p_prototype === Person.prototype is true
Person.prototype [ 'constructor', 'greeting', 'farewell' ]

因此,您可以得出以下结论:

  1. Person 类仅具有构造函数和原型(prototype)对象的预期属性,没有任何类定义的方法。

  2. 类的实例仅具有在构造函数中分配的预期数据属性,对象本身没有任何类定义的方法。

  3. 从实例获得的原型(prototype)与类的原型(prototype)相同(因此不会为每个实例创建新对象)。

  4. Person.prototype 具有来自 class 定义的预期方法,以及指向构造函数本身的属性(用于继承和调用派生类)构造函数)。

因此,您可以从中验证使用 class 语法定义的方法是否适用于 Classname.prototype 对象,并且该对象与所有实例共享。

关于javascript - 我们是否应该在 ES6 类的原型(prototype)中包含方法以提高性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57929094/

相关文章:

javascript - 将超时设置为无穷大时遇到问题

javascript - 为什么 Parse.User.current() 为 null?

c# - 在c#中创建一个实现多个接口(interface)的抽象类

scala - 继承

c# - Entity Framework 继承和关系

c++ - 指向抽象类的指针

javascript - 下划线模板无法访问数据模型

java - json ajax问题

swift - 在 swift 中使用另一个类初始值设定项中的类(或实例)属性

javascript - 从多个类中获取 id 值