Сохранить контекст этого - PullRequest
0 голосов
/ 12 мая 2018

Я нашел интересную проблему. Задача состоит в том, чтобы создать оболочку для всех дочерних функций, которая задержит реализацию.

function someFunc() {
  console.log(this.someProp);
}

var obj1 = {
  someProp: 1,
  method1: someFunc,
};

var obj2 = {
  someProp: 2,
  method2: someFunc,
};
Function.prototype.defer = function(ms) {
  let self = this;
  setTimeout(self, ms) //<<-- lose context(obj1, obj2)
};
obj1.method1(); // 1
obj2.method2(); // 2
obj1.method1.defer(1000); // 1 after 1 sec, now is undefined
obj2.method2.defer(1000); // 2 after 1 sec, now is undefined

Ответы [ 2 ]

0 голосов
/ 12 мая 2018

Прямые вызовы 'obj.method' работают, потому что когда функция вызывается как метод объекта, это устанавливается для объекта, к которому вызывается метод.

Функция отсрочки невызывается как метод объекта, он вызывается как метод Function, из которого он получает его this

Наименьшие изменения 'fix' в вашем коде:

function someFunc() {
  console.log(this.someProp);
}

var obj1 = {
  someProp: 1,
  method1: someFunc
};

var obj2 = {
  someProp: 2,
  method2: someFunc
};
Object.prototype.defer = function(func, ms) {
  typeof this[func] === 'function' && setTimeout(this[func].bind(this), ms) //<<-- lose context(obj1, obj2)
};
obj1.method1(); // 1
obj2.method2(); // 2
obj1.defer('method1', 1000); // 1 after 1 sec
obj2.defer('method2', 1000); // 2 after 1 sec

В зависимостив вашем реальном случае использования есть, вероятно, лучшие способы сделать это, чем добавлять методы к встроенным типам.Например, делая obj1, obj2 экземплярами объявленных вами новых классов, которые расширяют базовый класс в вашем коде, где вы предоставляете общие методы, такие как функция defer ().

0 голосов
/ 12 мая 2018

Попробуйте сохранить контекст выполнения, используя bind.bind() позволяет установить, к какому конкретному объекту будет привязан this при вызове функции или метода.

function someFunc() {
  console.log(this.someProp);
}

var obj1 = {
  someProp: 1,
  method1: someFunc,
};

var obj2 = {
  someProp: 2,
  method2: someFunc,
};
Function.prototype.defer = function(ms) {
  setTimeout(this, ms) //<<-- lose context(obj1, obj2)
};
obj1.method1(); // 1
obj2.method2(); // 2
obj1.method1.bind(obj1).defer(1000); // 1 after 1 sec, now is undefined
obj2.method2.bind(obj2).defer(1000); // 2 after 1 sec, now is undefined
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...