it-swarm.com.ru

ES6 - объявить метод-прототип в классе с помощью оператора import

Я использую классы ES6. Я хочу быть в состоянии сделать это:

function Car(color) {
  this.color = color;
};

Car.prototype.getColor = require('./getColor');

Где получить цвет это экспортируемая функция. я хочу иметь возможность импортировать функцию из внешнего файла и установить ее как метод-прототип в классе ES6. Это тот синтаксис, о котором я говорю:

class Car {
  constructor(color) {
    this.color = color;
  }

  getColor() {} // I want to import this function from './getColor', as above
}

Это выполнимо?

25
SheedySheedySheedy

Вы все еще можете прикрепить метод к class 'prototype; в конце концов, классы - это просто синтаксический сахар над «функциональным объектом», который является старым способом использования функции для конструирования объектов.

Поскольку вы хотите использовать ES6, я буду использовать импорт ES6.

Минимальные усилия при использовании прототипа:

import getColor from 'path/to/module';

class Car {
    ...
}

Car.prototype.getColor = getColor;

Как видите, вы все равно используете свойство prototype для присоединения метода, если захотите.


Вызов модуля в методе класса:

В качестве альтернативы, если вы не хотите использовать свойство prototype, вы всегда можете сделать так, чтобы ваш метод возвращал функцию из модуля:

import getColor from 'path/to/module';

class Car {
    getColor () {
        return getColor.call(this);
    }
}

Использование Геттера

Вы также можете быть немного хитрее и использовать «добытчик» для достижения этого другим способом.

import getColor from 'path/to/module';

class Car {
    get getColor () { return getColor.bind(this) }
}

Затем вы можете использовать его, просто позвонив, myInstanceOfCar.getColor()

Или в более семантическом использовании геттера:

class Car {
    get color () { return getColor.call(this) }
}

// ...

const color = myInstanceOfCar.color;

Имейте в виду, что геттеры/сеттеры не могут иметь то же имя, что и свойства, которые вы задали в конструкторе. В итоге вы превысите максимальный стек вызовов с бесконечной рекурсией, когда попытаетесь использовать установщик для установки того же свойства. Пример: set foo (value) { this.foo = value }


Свойства класса ES2016

Если вы используете Babel для переносаиспользуете экспериментальные предложения ) и хотите использовать некоторые ES2016, вы можете использовать следующий синтаксис (но имейте в виду, что это относится к метод к объекту напрямую, и не устанавливает его по прототипу):

import getColor from 'path/to/module';

class Car {
    getColor = getColor;
}

Необязательное связывание со свойствами класса

Если вы используете сокращенный синтаксис для установки свойства, вам не нужно будет связывать метод (настройка заключается в том, что свойство изменяет значение, на которое ссылается «this», по сути автоматически связывая его), но вы, безусловно, можете, должны вы выбираете (например, если вы хотите связать что-то еще):

getColor = getColor.bind(this);
28
ndugger

Да. Синтаксис class - это просто (очень сложный) синтаксический сахар для функций конструктора. Таким образом, Car по-прежнему будет функцией со свойством prototype, и вы можете сделать то же самое:

import getColor from './getColor';
// ...
Car.prototype.getColor = getColor;

Однако это делает метод перечисляемым, в отличие от методов, созданных из синтаксиса класса. Так что вы можете использовать Object.defineProperty вместо этого.

3
Felix Kling

Если вам интересно, я разработал небольшой модуль для привязки функций с различным количеством параметров к методам класса: https://github.com/ngryman/to-method .

const toMethod = require('to-method');

function Car(color) {
  this.color = color;
}

toMethod(Cat, { getColor: require('./getColor') });
0
ngryman