Автор: Дмитрий Павлютин Источник: дмитрипавлутин Переводчик: Front-end Xiaozhi
Ставь лайк и смотри, поиск в WeChat【Переезд в мир】Обратите внимание на этого человека, который не имеет большого фабричного прошлого, но имеет восходящий и позитивный настрой. эта статья
GitHub
GitHub.com/QQ449245884…Он был включен, статьи были классифицированы, и многие мои документы и учебные материалы были систематизированы.
Все говорили, что нет проекта для написания резюме, поэтому я помог вам найти проект, и это было с бонусом.【Учебник по строительству】.
Мне нравится менять указатель контекста выполнения функции в JS, также известный какthis
направление.
Например, мы можем использовать методы массива для массивоподобных объектов:
const reduce = Array.prototype.reduce;
function sumArgs() {
return reduce.call(arguments, (sum, value) => {
return sum += value;
});
}
sumArgs(1, 2, 3); // => 6
с другой стороны,this
Трудно понять.
Мы часто обнаруживаем, что используемthis
Указывая неправильно. Следующее научит вас, как простоthis
Привязка к нужному значению.
Прежде чем начать, мне нужна вспомогательная функцияexecute(func)
, который выполняет только функцию, предоставленную в качестве аргумента.
function execute(func) {
return func();
}
execute(function() { return 10 }); // => 10
Теперь продолжайте понимать окружающихthis
Характер ошибки: разделение методов.
1. Проблема разделения методов
Предположим, есть классPerson
содержит поляfirstName
а такжеlastName
. Кроме того, у него есть методgetFullName()
, который возвращает полное имя человека. Следующим образом:
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
this.getFullName = function() {
this === agent; // => true
return `${this.firstName} ${this.lastName}`;
}
}
const agent = new Person('前端', '小智');
agent.getFullName(); // => '前端 小智'
можно увидетьPerson
Функция вызывается как конструктор:new Person('前端', '小智')
. внутри функцииthis
Представляет вновь созданный экземпляр.
getfullname()
Возвращает полное имя человека:'前端 小智'
. как и ожидалось,getFullName()
в рамках методаthis
равныйagent
.
Если вспомогательная функция выполняетсяagent.getFullName
Что происходит с методом:
execute(agent.getFullName); // => 'undefined undefined'
Неверный результат выполнения:'undefined undefined'
,Этоthis
Укажите на проблему, вызванную неправильным.
сейчас наgetFullName()
метод,this
Значением является глобальный объект (в среде браузераwindow
).this
равныйwindow
,${window.firstName} ${window.lastName}
Результат выполнения есть'undefined undefined'
.
Это происходит потому, что при вызовеexecute(agent.getFullName)
Когда метод отсоединен от объекта. В основном происходит обычный вызов функции (не вызов метода):
execute(agent.getFullName); // => 'undefined undefined'
// 等价于:
const getFullNameSeparated = agent.getFullName;
execute(getFullNameSeparated); // => 'undefined undefined'
Это так называемый метод, отсоединенный от своего объекта, когда метод отсоединяется, а затем выполняется,this
Нет связи с исходным объектом.
Чтобы убедиться, что внутреннийthis
указать на правильный объект, который должен быть выполнен
- Выполните метод как метод доступа к свойству:
agent.getFullName()
- или статически
this
Привязать к содержащемуся объекту (используя стрелочные функции,.bind()
метод и др.)
проблемы разделения методов и, как следствие,this
Наведение неправильное, что обычно происходит в следующих ситуациях:
Перезвоните
// `methodHandler()`中的`this`是全局对象
setTimeout(object.handlerMethod, 1000);
При настройке обработчиков событий
// React: `methodHandler()`中的`this`是全局对象
<button onClick={object.handlerMethod}>
Click me
</button>
Затем введите некоторые полезные методы, а именно, как сделать метод отдельным от объектаthis
Укажите на нужный объект.
2. Закройте контекст
Держатьthis
Самый простой способ указать на экземпляр класса — использовать дополнительную переменнуюself
:
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
const self = this;
this.getFullName = function() {
self === agent; // => true
return `${self.firstName} ${self.lastName}`;
}
}
const agent = new Person('前端', '小智');
agent.getFullName(); // => '前端 小智'
execute(agent.getFullName); // => '前端 小智'
getFullName()
статически закрытоself
Переменная, эффективноthis
Делайте ручную привязку.
Теперь при звонкеexecute(agent.getFullName)
когда все работает нормально, потому чтоgetFullName()
в рамках методаthis
всегда указывайте правильное значение.
3. Используйте стрелочные функции
Есть ли способ статической привязки без дополнительных переменныхthis
? Да, это именно то, что делают стрелочные функции.
Рефакторинг с использованием стрелочных функцийPerson
:
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
this.getFullName = () => `${this.firstName} ${this.lastName}`;
}
const agent = new Person('前端', '小智');
agent.getFullName(); // => '前端 小智'
execute(agent.getFullName); // => '前端 小智'
Стрелочные функции связаны лексическиthis
. Проще говоря, он использует внешнюю функцию из своего определения.this
ценность .
Стрелочные функции рекомендуются во всех случаях, когда требуется использование внешнего контекста функции.
4. Привяжите контекст
Теперь давайте сделаем еще один шаг и воспользуемся рефакторингом классов в ES6.Person
.
class Person {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
getFullName() {
return `${this.firstName} ${this.lastName}`;
}
}
const agent = new Person('前端', '小智');
agent.getFullName(); // => '前端 小智'
execute(agent.getFullName); // => 'undefined undefined'
К сожалению, даже с новым синтаксисом классаexecute(agent.getFullName)
все еще возвращается“undefined undefined”
.
В случае классов используйте дополнительную переменнуюself
или стрелочные функции для исправленияthis
указание не работает.
Но естьbind()
Трюк с методом, который связывает контекст метода с конструктором:
class Person {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
this.getFullName = this.getFullName.bind(this);
}
getFullName() {
return `${this.firstName} ${this.lastName}`;
}
}
const agent = new Person('前端', '小智');
agent.getFullName(); // => '前端 小智'
execute(agent.getFullName); // => '前端 小智'
в конструктореthis.getFullName = this.getFullName.bind(this)
методgetFullName()
Привязать к экземпляру класса.
execute(agent.getFullName)
Работает как положено, возвращается'前端 小智'
.
5. Метод толстой стрелки
bind
Этот метод слишком многословен, мы можем использовать метод толстой стрелки:
class Person {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
getFullName = () => {
return `${this.firstName} ${this.lastName}`;
}
}
const agent = new Person('前端', '小智');
agent.getFullName(); // => '前端 小智'
execute(agent.getFullName); // => '前端 小智'
метод толстой стрелкиgetFullName =() =>{…}
Привязывается к экземпляру класса, даже если метод отсоединен от своего объекта.
Этот метод связан в классеthis
самый эффективный и лаконичный метод.
6. Резюме
Метод, отсоединенный от объекта, может привести к неправильной ссылке this. связывать статическиthis
, вы можете вручную использовать дополнительную переменнуюself
чтобы сохранить правильный объект контекста. Однако лучшей альтернативой является использование стрелочных функций, которые, по сути, предназначены для лексического связывания.this
.
На уроке можно сделать用bind()
для ручной привязки метода класса в конструкторе. Конечно, если вы не используетеbind
Этот многословный метод также может быть представлен лаконичной и удобной жирной стрелкой.
оригинал:GitHub.com/Валентино Г.А.…
Ошибки, которые могут существовать после развертывания кода, не могут быть известны в режиме реального времени.Чтобы решить эти ошибки впоследствии, много времени тратится на отладку журнала.Кстати, я рекомендую всем полезный инструмент мониторинга ошибок.Fundebug.
общаться с
Статья постоянно обновляется каждую неделю. Вы можете выполнить поиск «Big Move to the World» в WeChat, чтобы прочитать и обновить ее как можно скорее (на одну или две статьи раньше, чем в блоге). Эта статья находится на GitHub.GitHub.com/QQ449245884…Он был включен, и многие мои документы были разобраны. Добро пожаловать в Звезду и совершенство. Вы можете обратиться в тестовый центр для ознакомления во время собеседования. Кроме того, обратите внимание на паблик-аккаунт и ответьте в фоновом режиме.Благосостояние, вы можете увидеть преимущества, вы знаете.