2015-06-08 4 views
5



При поиске в документации ES6 ARROW функций на Mozilla документации, я должен знать, что функции Arrow применяет все правила строгого режима, за исключением одного, как описано в link
Компиляция ES6 стрелка функции в ES5 с использованием Babel.js

var f =() => { 'use strict'; return this}; 
 
    var g = function() { 'use strict'; return this;} 
 

 
    console.log(f()); //prints Window 
 
    console.log(g()); // prints undefined 
 

 
    //we can test this in firefox!

Но Babel.js является transpiling функцию стрелки код для ES5 кода, который возвращает undefined, а не Window (demo link)

"use strict"; 
 

 
setTimeout(function() { 
 
    return undefined; 
 
}, 100);

Таким образом, выше фрагмент является выходом из Babel.js. Разве это не могло быть ниже?

"use strict"; 
 

 
setTimeout(function() { 
 
    return this; 
 
}.bind(Window), 100);

Если я пишу ES6, я ожидал бы Window, а не undefined
Является ли это ошибка?
ИЛИ, я ничего не понял?

+0

Babel ставит все в строгом режиме. 'undefined' выглядит корректно. – elclanrs

+1

@elclanrs Это правильно с точки зрения ES5, поскольку код передается в ES5, но в случае функции стрелки в ES6 это должно быть «окно». – dfsq

+2

@dfsq почему это должно быть окно? Он будет наследовать «это» из инкапсулирующего объекта, который не определен; не глобальный. Или я ошибаюсь, думая об этом? – vol7ron

ответ

6

tl; dr: Babel предполагает, что каждый файл является модулем. Модули строгие по умолчанию и их значение this составляет undefined.


Это рассматривается в Babel FAQ:

Бабель предполагает, что все входные коды модуль ES2015. Модули ES2015 неявно строгие, поэтому это означает, что верхний уровень this не является window в браузере и не является exports в узле.

Если вы не хотите этого, то у вас есть возможность отключить строгий трансформатор:

$ babel --blacklist strict script.js 

require("babel").transform("code", { blacklist: ["strict"] }); 

ОБРАТИТЕ ВНИМАНИЕ: Если вы сделаете это, вы охотно отклоняясь от спецификации, и это может привести к будущему проблемы взаимодействия.

См. strict transformer docs для получения дополнительной информации.

2

Вы в принципе правы, как описано на странице MDN. Однако Бабель всегда помещает 'use strict' в корневую область. В результате компиляции следующее:

'use strict'; 
var f =() => { 'use strict'; return this}; 

В таком случае строгие правила делать применяются. См. Скомпилированный пример here. Вавилон даже оптимизирует верхний уровень this, так как он гарантированно будет undefined.

+0

Вот что я сомневаюсь ... Я ожидаю, что вывод будет 'Window' и будет писать мой код ... Итак, как это могло быть справедливо? – Navaneeth

+3

@Navaneeth Когда '' use strict'' является первым выражением в скрипте, глобальный объект 'this' становится неопределенным [(см. Здесь)] (https://developer.mozilla.org/en-US/docs/Web /JavaScript/Reference/Strict_mode#.22Securing.22_JavaScript). Это также относится к другим блокам, где это наследуется от глобальной области. Попробуйте, например. '(function() {console.log (this);})()' и '(function() {'use strict'; console.log (this);})()'. Поскольку Babel работает полностью в строгом режиме, его компилятор правильно предполагает, что «это» не определено в глобальной области. Если вы хотите получить доступ к объекту 'window', просто сделайте это явно. – lyschoening

Смежные вопросы