На самом деле, это клише. Есть много статей об этом. На самом деле, я думал, что понял это, но вчера я все еще немного сомневался во время проекта. Я думал о подробной статье, которую я собрал и читал в JavaScript Weekly (позже была ссылка, и китайский перевод на редкоземельные Земли был прикреплен) и еще одна статья, рекомендованная старшим, поэтому я посмотрел на них, и мое понимание этого действительно немного улучшилось.
«Это» в JavaScript является динамическим и определяется при выполнении функции, а не при объявлении функции. Все функции могут вызвать «это», что не имеет значения, принадлежит ли функция объекту. Что касается этого, в основном четыре ситуации.
1. Метод, используемый в качестве объекта, называется
Если функция - это метод, который рассматривается как объект, то эта функция указывает на объект;
var John = {firstname: "John"} function func () {alert (this.firstname + ": hi!")} john.sayhi = func john.sayhi () // this = ДжонЗдесь стоит отметить что -то. Когда метод объекта вынесен и назначен переменной, метод становится триггером функции, и этот указывает на окно или недостаток (строгий режим).
2. Вызов в функции
Когда эта функция имеет это, это фактически означает, что она называется методом. Вызов между ними эквивалентно обработке как окно -объект. Это указывает на окно. Стоит отметить, что ES5 фактически предусматривает, что это = неопределенное, и только браузеры все еще выполняются в соответствии со старым методом (я тестирует его в последней версии Chrome, Safari и Firefox, все указывают на Window (201607) и используйте строгий режим, чтобы указывать на неопределенные под Firefox;
func () function func () {alert (this) // [Object Window] или [Object Global] или вид ..}Чтобы передать это, () должен быть ориентировочным типом, похожим на OBJ.A или OBJ ['A'], и не может быть чем -то еще.
Здесь также есть небольшая яма. Когда в методе объекта существует функция, функция фактически запускается в качестве режима функции, поэтому это по умолчанию в окно (не определен в строгом режиме). Решение состоит в том, чтобы связать это с функцией.
var numbers = {numbera: 5, numberb: 10, sum: function () {console.log (this === numbers); // => true function canculate () {// это окно или не определен в строгой режиме console.log (this === numbers); // => false return this.numbera + this.numberb; } return Countulate (); }}; number.sum (); // => nan или throws typeerror в строгом режиме var numbers = {numbera: 5, numberb: 10, sum: function () {console.log (this === number); // => true function canculate () {console.log (this === numbers); // => true вернуть this.numbera + this.numberb; } // Использовать метод .call () для изменения контекста возврата return calculate.call (this); }}; number.sum (); // => 153. Позвоните в новый
Переменная, которая ссылается на объект, фактически сохраняет ссылку на объект, то есть переменная фактически сохраняет указатель на реальные данные.
При использовании нового ключевого слова это изменение фактически предпринимает следующие шаги:
Создайте это = {}.
Это может быть изменено во время выполнения новых, а затем добавляются атрибуты и методы;
Возвращает это изменилось.
Функция животного (имя) {this.name = name this.canwalk = true} var Animal = new Animal ("Beastie") Alert (Animal.name)Следует отметить, что если конструктор возвращает объект, это указывает на возвращенный объект;
function Animal () {this.name = 'mousie'; this.age = '18'; return {name: 'Godzilla'} // <- будет возвращено} var Animal = new Animal () console.log (Animal.name) // Годзилла Консоль.log (Animal.age) // НеопределеноЗдесь важно отметить, что не забудьте использовать новую, иначе новая функция не будет создана. Вместо этого он просто выполняет функцию, которая эквивалентна вызову функции, и это фактически указывает на окно
Функция транспортного средства (тип, weelscount) {this.type = type; this.wheelscount = weelscount; вернуть это;} // функция vlocationvar car = exatur ('car', 4); car.type; // => 'CAR' CAR.WHEELSCOUNT // => 4 CAR === Window // => true4. четко позвоните в это, используйте звонок и примените
Это самое место в стиле JavaScript.
Следующий код:
func.call(obj, arg1, arg2,...)
Первый параметр будет использоваться в качестве эталонного объекта этого, а последующий параметр будет использоваться в качестве параметра функции. Решение состоит в том, чтобы использовать Bind.
Функция животного (тип, ноги) {this.type = type; this.legs = ноги; this.loginfo = function () {console.log (this === mycat); // => true console.log ('the' + this.type + 'имеет' + this.legs + 'ноги'); };} var mycat = new Animal ('Cat', 4); // журналы "Кошка имеет 4 ножки" settimeout (mycat.loginfo.bind (mycat), 1000); // settimeout ?? var John = {FirstName: "John", инцидент: "smith"} function func (a, b) {alert (this [a] + '' + this [b])} func.call (Джон, 'FirstName', 'Farmame') // "Джон Смит"Что касается применения, то он просто проходит в параметрах в квадрате массива, а другие части одинаковы, как следующее:
Func.call (Джон, «FirstName», «Farmame») FunC.Apply (Джон, [FirstName ',' Farmame '])
Они также могут быть использованы в классе наследование в ES5, чтобы вызвать родительский конструктор.
функция Runner (name) {console.log (этот экземпляр кролика); // => true this.name = name; } function rabbit (name, dusttlegs) {console.log (этот экземпляр кролика); // => true // косвенно называемый, родительский конструктор Runner.call (это, имя); this.countlegs = gultlegs; } var myrabbit = new Rabbit ('White Rabbit', 4); Мираббит; // {name: 'белый кролик', gultlegs: 4}5..bind ()
Сравните методы .apply () и .call (), оба из которых немедленно выполняют функцию, в то время как функция .bind () возвращает новый метод, который связывает этот предварительно определенный и может задержать вызов.
Функция метода .bind () заключается в создании новой функции. Контекст во время выполнения является первым параметром, передаваемым .bind (), который позволяет создавать функцию, которая имеет эту предустановку.
var numbers = {Array: [3, 5, 10], getNumbers: function () {return this.Array; }}; // Создать связанную функцию BuldgetNumbers = numbers.getNumbers.bind (numbers); BoundgetNumbers (); // => [3, 5, 10] // Извлечение метода из ObjectVar SimpleGetNumbers = numbers.getNumbers; SimplegetNumbers (); // => неопределенная или бросает ошибку в строгом режимеПри использовании .bind () вы должны отметить, что .bind () создает вечную контекстную цепь и не подлежит изменению. Даже если функция привязки использует .call () или .apply () для перехода в другие различные контексты, она не изменит контекст своего предыдущего соединения, и повторение не будет играть какую -либо роль.
Только когда называется конструктор, функция связывания может изменить контекст, но это не особенно рекомендуемый подход.
6. Функция стрелы
Функция стрелки не создает контекст своего собственного выполнения, так что это зависит от внешней функции, которую она определяется во время определения.
Функции стрел не могут быть изменены после привязки контекста один раз, даже если используется метод изменения контекста:
var numbers = [1, 2]; (function () {var get = () => {console.log (this === numbers); // => true return this;}; console.log (this === numbers); // => true get (); // => [1, 2] // Функции Arrow используют .apply () и .call () get.call (0]); // => [1, 2] // связывать get.bind ([0]) ();Это связано с тем, что функция стрелки имеет статический контекст и не будет изменяться из -за разных вызовов. Поэтому не используйте функции стрел для определения методов
период функции (часы, минуты) {this.hours = часы; this.minutes = минуты; } Perior.prototype.format = () => {console.log (это === window); // => true вернуть это.hours + 'часы и' + this.minutes + 'минуты'; }; var walkperiod = новый период (2, 30); walkperiod.format (); // => 'Неопределенные часы и неопределенные минуты'обратиться к
Четыре аромата "это"
Нежное объяснение «этого» ключевого слова в JavaScript
JavaScript эта тайна (перевод)
Настоятельно рекомендуется, чтобы студенты, которые этого не понимают. Проверьте три вышеуказанные статьи, третья - это перевод второй. Если у вас есть какие -либо вопросы по этому поводу, вы можете обсудить вместе, общаться и продвигать мышление и добиться прогресса вместе.