Учитывая это:
import { logText, Example } from 'example';
Возможно ли конечному пользователю изменить logText?
Поскольку вы не очень точно понимаете, что вы имеете в виду под "изменить logText", я рассмотрю несколько вариантов:
Можете ли вы переназначить какую-либо другую функцию на переменную logText
?
Нет. Тебе этого не сделать. Когда вы используете import
, создается переменная const
, которой нельзя присвоить. Даже если это не const, это просто локальный символ, который в любом случае не повлияет на использование другим модулем logText()
. Механизм import
разработан таким образом специально. Предполагается, что загрузчик вашего модуля не сможет заменить внутренние части реализации модуля, которые не были специально предназначены для замены.
Можно ли изменить код внутри функции logText
снаружи модуля, в котором она содержится?
Нет, вы не можете. Код в модулях живет внутри своей собственной области функций, что обеспечивает конфиденциальность. Вы не можете изменять код внутри этого модуля извне модуля.
Можете ли вы заменить функцию logText()
внутри модуля так, чтобы реализация Example
внутри этого класса использовала вашу функцию logText()
?
Нет, вы не можете сделать это снаружи модуля. Вы должны будете на самом деле изменить сам код модуля, или кто-то должен будет разработать интерфейс Example, чтобы иметь заменяемую или модифицируемую функцию logText()
, которую использовал объект Example.
Например, logText()
можно сделать методом в Example, а затем вы можете переопределить его своей собственной реализацией, что приведет к тому, что реализация Example будет использовать ваше переопределение.
Код в модуле, который вы не изменяете:
export class Example {
constructor(){
this.logText();
}
logText() {
console.log('some text');
}
}
Код, выполняющий импорт:
import { Example } from 'example';
class MyExample extends Example {
constructor() {
super();
}
logText() {
console.log("my own text");
}
}
let o = new MyExample();
Можете ли вы создать собственную версию logText
и использовать ее локально?
Конечно, вы можете сделать это.
function myLogText() {
do your own thing
}
И вы даже НЕ можете импортировать logText, чтобы вы могли использовать имя символа logText()
локально, если хотите. Но это никак не повлияет на то, что делает Пример.
Существуют ли способы разработки примера модуля, чтобы можно было легко заменить logText()
.
Да, есть много способов сделать это. Я показал выше, что делает logText
метод, который можно переопределить. Он также может быть передан в качестве необязательного аргумента конструктору Example
.
Может даже быть экспортированный объект, который позволил бы вызывающей стороне заменить свойства этого объекта. Например:
export const api = {
logText: function logText(){
console.log('some text');
}
};
export class Example {
constructor(){
api.logText();
}
}
Затем используйте это так:
import { api, Example } from 'example';
api.logText = function() {
console.log('my Text');
};
Я бы вообще не рекомендовал это, потому что это настраивает вас на конфликты использования между несколькими пользователями одного и того же модуля, где каждый пытается модифицировать его глобально способами, которые конфликтуют друг с другом. Модель подклассов (упомянутая выше) позволяет каждому использованию модуля настраивать по-своему, не вступая в конфликт с другими использованиями модуля.