2015-02-06 4 views
28

В нескольких местах я читал, что ключевым отличием является то, что « лексически связан функциями стрелок». Это все хорошо и хорошо, но я не знаю, что это значит.Что означает «это» в стрелочных функциях в ES6?

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

var testFunction =() => { console.log(this) }; 
testFunction(); 
+3

Он просто фиксирует значение 'this' от объема, содержащего, рассматривая его как любой переменная. – Barmar

+1

Это просто значит, что вам не нужно делать kludge из 'var self = this;', а затем использовать 'self' в функции. – Barmar

+4

В вашем случае нет закрывающего контекста, или это глобальный контекст или контекст модуля, поэтому 'this' - это то, что в этом случае, скорее всего, null или window. Другими словами, 'this' имеет точно такое же значение, как если бы вы добавили' console.log (this) 'перед назначением функции. –

ответ

19

Arrow functions capture the this value of the enclosing context

function Person(){ 
    this.age = 0; 

    setInterval(() => { 
    this.age++; // |this| properly refers to the person object 
    }, 1000); 
} 

var p = new Person(); 

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

+3

@torazaburo запоздалый ответ - ответ зависит от того, где был размещен фрагмент кода в исходном вопросе. Если он был на верхнем уровне, 'this' является объектом' window', если мы находимся в браузере и 'module.exports', если мы находимся в среде Node. Дело в том, что функция стрелки * не имеет эффекта * на значение 'this'. – Aerovistae

+2

Комментарий от @dave, '' this' внутри вашей функции стрелки будет иметь то же значение, что и раньше, прежде чем функция стрелки была назначена ', - вот что, наконец, застало меня щелкнуть. – Kevin

1

Надеюсь, это показ кода может дать вам более четкую идею. В принципе, «это» в функции стрелок является текущей версией контекста «this». См. Код:

// 'this' in normal function & arrow function 
var this1 = { 
    number: 123, 
    logFunction: function() { console.log(this); }, 
    logArrow:() => console.log(this) 
}; 
this1.logFunction(); // Object { number: 123} 
this1.logArrow(); // Window 
5

Для того чтобы предоставить общую картину, я собираюсь объяснить как динамическую, так и лексическую привязку.

Динамическое связывание Имя

this относится к объекту метод вызывается. Это регулярно читаемое предложение на SO. Но это все еще только фраза, довольно абстрактная. Есть ли соответствующий шаблон кода для этого предложения?

Да есть:

const o = { 
    m() { console.log(this) } 
} 

// the important patterns: applying methods 

o.m(); // logs o 
o["m"](); // logs o 

m является метод, поскольку он опирается на this. o.m() или o["m"]() означает, что m применяется к o. Эти шаблоны - это перевод Javascript на нашу знаменитую фразу.

Существует еще один важный шаблон кода, который вы должны обратить внимание на:

"use strict"; 

const o = { 
    m() { console.log(this) } 
} 

// m is passed to f as a callback 
function f(m) { m() } 

// another important pattern: passing methods 

f(o.m); // logs undefined 
f(o["m"]); // logs undefined 

Он очень похож на предыдущий образец, только круглые скобки отсутствуют. Но последствия значительны: когда вы передаете m функции f, вы вытаскиваете m своего объекта/контекста o. Теперь он выкорчеван и this ничего не говорит (предполагается строгий режим).

лексические (или статический) Имя Binding

функции стрелки не имеют свои собственные this/super/arguments переплета. Они наследуют их от родительского лексической области:

const toString = Object.prototype.toString; 
 

 
const o = { 
 
    foo:() => console.log("window", toString.call(this)), 
 
     
 
    bar() { 
 
    const baz =() => console.log("o", toString.call(this)); 
 
    baz(); 
 
    } 
 
} 
 

 
o.foo() // logs window [object Window] 
 
o.bar() // logs o [object Object]

Помимо глобальной области (Window в браузерах) только функции способны сформировать область в JavaScript (и {} блоков в ES2015).Когда вызывается функция стрелки o.foo, нет никакой функции, из которой baz может наследовать ее this. Следовательно, он фиксирует привязку глобальной области действия, которая привязана к объекту Window.

Когда baz вызывается o.bar, функция стрелки окружена o.bar (o.bar формирует свою родительскую лексическую область) и может наследовать o.bar «ы this связывания. o.bar был вызван на o и, следовательно, его this связан с o.

0

Вы можете попробовать, чтобы понять это, следуя пути ниже

// whatever here it is, function or fat arrow or literally object declare 
// in short, a pair of curly braces should be appeared here, eg: 
function f() { 
    // the 'this' here is the 'this' in fat arrow function below, they are 
    // bind together right here 
    // if 'this' is meaningful here, eg. this === awesomeObject is true 
    console.log(this) // [object awesomeObject] 
    let a = (...param) => { 
    // 'this is meaningful here too. 
    console.log(this) // [object awesomeObject] 
} 

так «это» в функции стрелка жир не связан, означает, что вы не можете сделать что-нибудь привязать к «это» здесь, .Нанесите выиграл 't, .call не будет, .bind не будет. «это» в функции толстой стрелки привязывается при записи текста кода в текстовом редакторе. «Это» в функции толстой стрелки здесь буквально значимо. Что ваш код писать здесь, в текстовом редакторе, то, что ваше приложение работает там в repl. «Это», связанное с жирным заключением, никогда не изменится, если вы не измените его в текстовом редакторе. Извините за мой бассейн английского ...

функция
1

Стрелка this указывает на окружающий родителя в ES6, означает, что она не сфера, как анонимные функции в ES5 ...

Это очень полезный способ, чтобы избежать назначения вар самостоятельно к этому, который широко используется в ES5 ...

Посмотрите на примере ниже, назначая функцию внутри объекта:

var checkThis = { 
    normalFunction: function() { console.log(this); }, 
    arrowFunction:() => console.log(this) 
}; 

checkThis.normalFunction(); //Object {} 
checkThis.arrowFunction(); //Window {external: Object, chrome: Object, document: document, tmpDebug: "", j: 0…}