为什么在使用babel-loader时Object.assign()需要polyfill?

时间:2015-08-21 19:46:46

标签: javascript ecmascript-6 webpack babeljs

我正在尝试在Babel使用webpack编译的ES6 Web应用程序中使用function gaCrossDomain(url) { ga(function(tracker) { var linker = new window.gaplugins.Linker(tracker); var output = linker.decorate(url); }); } ,但我收到错误:

Object.assign()

我已经使用babel-loader将ES6转换为ES5,所以我的所有其他ES6代码都在运行。但是,Uncaught TypeError: Object.assign is not a function 仅在我的代码库中Object.assign()之后才有效。我看到我也可以修复此by importing babel-runtime,但我想了解为什么 import "babel-core/polyfill"需要的内容超过Object.assign()执行的内容 - 不应该{{} 1}}预处理所有内容,包括babel-loader

4 个答案:

答案 0 :(得分:55)

Babel,通过babel-loader,转换了ES6 语法的差异。 Babel本身在ES6标准库功能(如Object.assign)中无需添加任何内容。加载polyfill会为您加载单独的polyfill core-js,但您可以加载任何所需的polyfill。

甚至一些语法转换依赖于特定的polyfill功能来加载,因为某些语法依赖于库代码中实现的算法和行为。 http://babeljs.io/docs/learn-es2015/上的ES6功能列出了假定已加载的标准库功能。

答案 1 :(得分:12)

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兼容代码的转换器。

答案 2 :(得分:8)

如果您转到兼容性,您可以在Web和Mobile上看到object.assign不支持 IE 11 。它也为你提供了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

https://www.npmjs.com/package/object-assign

答案 3 :(得分:1)

我遇到了同样的问题。我认为在得到babel支持的情况下,可以安全使用所有ES2015 +功能。但是如上所述,babel polyfill仅填充语法,而不包含函数(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方法保持不变\ _(ツ)_ /