为什么在使用 babel-loader 时 Object.assign() 需要一个 polyfill?
Why does Object.assign() require a polyfill when babel-loader is being used?
我试图在 Babel 和 webpack 编译的 ES6 网络应用程序中使用 Object.assign()
,但出现错误:
Uncaught TypeError: Object.assign is not a function
我已经在使用 babel-loader
to transpile ES6 to ES5, so all my other ES6 code is working. Yet, Object.assign()
only works after I also import "babel-core/polyfill"
in my codebase. I see that I can also fix this ,但我想了解 为什么 Object.assign()
需要比 babel-loader
执行的更多 — babel-loader
不应该预处理所有内容,包括 Object.assign()
?
Babel,通过 babel-loader
,转换 ES6 语法 中的差异。 Babel 本身绝对不会添加任何 ES6 标准库功能(比如 Object.assign
)。加载 polyfill 会为您加载一个单独的 polyfill core-js
,但您可以加载任何您想要的 polyfill。
甚至某些语法转换也依赖于加载特定的 polyfill 功能,因为某些语法依赖于库代码中实现的算法和行为。 http://babeljs.io/docs/learn-es2015/ 上的 ES6 特性分别列出了假定已加载的标准库功能。
Object.assign()
是一个新的 API,它是 ES6 规范的一部分,因此它还没有在大多数浏览器中实现。参见:https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
因此,当您导入 babel-core/polyfill
时,它会为此添加 polyfill,以及其他新的 API,以便您的 ES6 代码可以使用它们。
babel-loader
只是将 ES6 语法转换为 ES5 兼容代码的转译器。
如果您向下查看兼容性,您会看到 IE 11 在 Web 和移动设备中都不支持 object.assign。它还为您提供了 pollyfill。
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
if (typeof Object.assign != 'function') {
Object.assign = function(target, varArgs) {
'use strict';
if (target == null) { // TypeError if undefined or null
throw new TypeError('Cannot convert undefined or null to object');
}
var to = Object(target);
for (var index = 1; index < arguments.length; index++) {
var nextSource = arguments[index];
if (nextSource != null) { // Skip over if undefined or null
for (var nextKey in nextSource) {
// Avoid bugs when hasOwnProperty is shadowed
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
to[nextKey] = nextSource[nextKey];
}
}
}
}
return to;
};
}
如果使用 Babel
https://babeljs.io/docs/plugins/transform-object-assign/
如果使用 NPM
我遇到了同样的问题。我认为在 babel 的支持下我可以安全地使用所有 ES2015+ 特性。但正如上面提到的,babel polyfills 仅语法,而不是函数(Object.assign,Array.includes 仅举几例)。
对于 Object.assign 我不喜欢使用 polyfill,而是使用扩展运算符。在这种情况下,如果找不到,babel 实际上会填充 Object.assign。看看这段代码:
let obj = {a: 1};
let obj2 = {...obj};
let obj3 = Object.assign({}, obj);
它将被 babel 压缩到:
"use strict";
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var obj = { a: 1 };
var obj2 = _extends({}, obj);
var obj3 = Object.assign({}, obj);
对于传播运算符,babel 会尝试使用原生 Object.assign 方法,如果找不到则使用 polyfill。
但是显式 Object.assign 方法保持不变 ¯\_(ツ)_/¯
我试图在 Babel 和 webpack 编译的 ES6 网络应用程序中使用 Object.assign()
,但出现错误:
Uncaught TypeError: Object.assign is not a function
我已经在使用 babel-loader
to transpile ES6 to ES5, so all my other ES6 code is working. Yet, Object.assign()
only works after I also import "babel-core/polyfill"
in my codebase. I see that I can also fix this Object.assign()
需要比 babel-loader
执行的更多 — babel-loader
不应该预处理所有内容,包括 Object.assign()
?
Babel,通过 babel-loader
,转换 ES6 语法 中的差异。 Babel 本身绝对不会添加任何 ES6 标准库功能(比如 Object.assign
)。加载 polyfill 会为您加载一个单独的 polyfill core-js
,但您可以加载任何您想要的 polyfill。
甚至某些语法转换也依赖于加载特定的 polyfill 功能,因为某些语法依赖于库代码中实现的算法和行为。 http://babeljs.io/docs/learn-es2015/ 上的 ES6 特性分别列出了假定已加载的标准库功能。
Object.assign()
是一个新的 API,它是 ES6 规范的一部分,因此它还没有在大多数浏览器中实现。参见:https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
因此,当您导入 babel-core/polyfill
时,它会为此添加 polyfill,以及其他新的 API,以便您的 ES6 代码可以使用它们。
babel-loader
只是将 ES6 语法转换为 ES5 兼容代码的转译器。
如果您向下查看兼容性,您会看到 IE 11 在 Web 和移动设备中都不支持 object.assign。它还为您提供了 pollyfill。
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
if (typeof Object.assign != 'function') {
Object.assign = function(target, varArgs) {
'use strict';
if (target == null) { // TypeError if undefined or null
throw new TypeError('Cannot convert undefined or null to object');
}
var to = Object(target);
for (var index = 1; index < arguments.length; index++) {
var nextSource = arguments[index];
if (nextSource != null) { // Skip over if undefined or null
for (var nextKey in nextSource) {
// Avoid bugs when hasOwnProperty is shadowed
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
to[nextKey] = nextSource[nextKey];
}
}
}
}
return to;
};
}
如果使用 Babel
https://babeljs.io/docs/plugins/transform-object-assign/
如果使用 NPM
我遇到了同样的问题。我认为在 babel 的支持下我可以安全地使用所有 ES2015+ 特性。但正如上面提到的,babel polyfills 仅语法,而不是函数(Object.assign,Array.includes 仅举几例)。 对于 Object.assign 我不喜欢使用 polyfill,而是使用扩展运算符。在这种情况下,如果找不到,babel 实际上会填充 Object.assign。看看这段代码:
let obj = {a: 1};
let obj2 = {...obj};
let obj3 = Object.assign({}, obj);
它将被 babel 压缩到:
"use strict";
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var obj = { a: 1 };
var obj2 = _extends({}, obj);
var obj3 = Object.assign({}, obj);
对于传播运算符,babel 会尝试使用原生 Object.assign 方法,如果找不到则使用 polyfill。 但是显式 Object.assign 方法保持不变 ¯\_(ツ)_/¯