JavaScript - Расширение встроенных объектов против расширения собственных объектов - PullRequest
0 голосов
/ 25 апреля 2020

Мне интересно следующее поведение JavaScript. Когда я хотел бы расширить стандартный встроенный объект, скажем, Math, я мог бы просто использовать точку для создания метода на нем.

Например:

Math.sum = function(a, b) {
  return a + b;
}

Тем не менее, когда я захочу расширить свои собственные объекты, мне придется использовать прототип.

Надеюсь, кто-нибудь сможет меня просветить.

1 Ответ

3 голосов
/ 25 апреля 2020

Тем не менее, когда я хочу расширить свои собственные объекты, мне придется использовать прототип.

Нет, вы не делаете:

function Example() {
}
Example.sum = function(a, b) {
    return a + b;
};
console.log(Example.sum(1, 2)); // 3

Когда вы присваиваете свойству функции , вы вызываете ее непосредственно для этой функции (как и для вашего Math.sum). Обычно они называются stati c методы .

Когда вы присваиваете свойство объекту prototype функции, вы добавляете его к объекту, который будет использоваться как прототип для нового объекта, если вы используете эту функцию в качестве конструктора , обычно через new:

const e = new Example();

Они называются методами прототипа : методы объекта наследует от своего прототипа.

Вот мой пример выше с использованием метода stati c (sum) и прототипа с использованием старого синтаксиса ES5:

function Example(x) {
    this.x = x;
}
Example.sum = function(a, b) {
    return a + b;
};
Example.prototype.add = function(y) { // DON'T DO THIS (not in this way), keep reading
    return this.x + y;
};
console.log(Example.sum(1, 2)); // 3
var e = new Example(1);
console.log(e.add(2)); // 3

Но , я настоятельно рекомендую не создавать методы-прототипы с помощью присваивания; вместо этого используйте Object.defineProperty:

function Example(x) {
    this.x = x;
}
Example.sum = function(a, b) {
    return a + b;
};
Object.defineProperty(Example.prototype, "add", {
    value: function(y) {
        return this.x + y;
    },
    writable: true,
    configurable: true,
    enumerable: false // <== This is the default, but for emphasis
});
console.log(Example.sum(1, 2)); // 3
var e = new Example(1);
console.log(e.add(2)); // 3

Причиной этого является то, что свойство, ссылающееся на функцию add, является не перечисляемым (не отображается в for-in loop или Object.keys, et c.).


Далее, в 2020 году, я бы использовал синтаксис class (если бы я хотел использовать функцию конструктора с * 1057) * объект, который я использовал с new):

class Example {
    constructor(x) {
        this.x = x;
    }
    static sum(a, b) {
        return a + b;
    }
    add(y) {
        return this.x + y;
    }
}
console.log(Example.sum(1, 2)); // 3
const e = new Example(1);
console.log(e.add(2)); // 3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...