简体   繁体   English

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

[英]Why does Object.assign() require a polyfill when babel-loader is being used?

I'm attempting to use Object.assign() in an ES6 web app compiled by Babel with webpack, but I'm getting an error: 我试图在Babel使用webpack编译的ES6 Web应用程序中使用Object.assign() ,但是我收到一个错误:

Uncaught TypeError: Object.assign is not a function

I'm already using babel-loader to transpile ES6 to ES5, so all my other ES6 code is working. 我已经使用babel-loader将ES6转换为ES5,所以我所有的其他ES6代码都正常工作。 Yet, Object.assign() only works after I also import "babel-core/polyfill" in my codebase. 然而, Object.assign()仅在我在代码库中import "babel-core/polyfill"之后才有效。 I see that I can also fix this by importing babel-runtime , but I'd like to understand why Object.assign() requires more than what babel-loader performs — shouldn't babel-loader preprocess everything, including Object.assign() ? 我看到我也可以通过导入babel-runtime来解决这个问题,但是我想理解为什么 Object.assign()需要的不仅仅是babel-loader执行的操作 - 不应该babel-loader预处理所有内容,包括Object.assign()

Babel, via babel-loader , transpiles differences in ES6 syntax . Babel,通过babel-loader ,解决了ES6 语法的差异。 Babel on its own does absolutely nothing to add in ES6 standard library functionality (like Object.assign ). Babel本身在ES6标准库功能(如Object.assign )中无需添加任何内容。 Loading the polyfill loads a separate polyfill core-js for you, but you can load any polyfill you want. 加载polyfill会为您加载单独的polyfill core-js ,但您可以加载任何所需的polyfill。

Even some syntax conversions rely on specific polyfill functionality to be loads, since some syntax relies on algorithms and behaviors implemented in library code. 甚至一些语法转换依赖于特定的polyfill功能来加载,因为一些语法依赖于库代码中实现的算法和行为。 The ES6 features on http://babeljs.io/docs/learn-es2015/ each list what standard library functionality are assumed to have been loaded. http://babeljs.io/docs/learn-es2015/上的ES6功能列出了假定已加载的标准库功能。

Object.assign() is a new API that's part of ES6 spec, so it's not implemented in most browsers yet. Object.assign()是一个新的API,它是ES6规范的一部分,所以它还没有在大多数浏览器中实现。 See: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign 请参阅: https//developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

So when you import babel-core/polyfill , it adds polyfills to this, and other new APIs, so that your ES6 code can use them. 因此,当您导入babel-core/polyfill ,它会向此添加polyfill,以及其他新API,以便您的ES6代码可以使用它们。

babel-loader is just the transpiler that converts ES6 syntax to ES5 compatible code. babel-loader只是将ES6语法转换为ES5兼容代码的转换babel-loader

If you go down to Compatibility you can see IE 11 is not supported in both Web and Mobile for object.assign. 如果您转到兼容性,您可以看到对于object.assign,Web和Mobile都不支持IE 11 It also gives you the pollyfill for that. 它还为您提供了pollyfill。

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign 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;
  };
 }

If using Babel 如果使用巴别塔

https://babeljs.io/docs/plugins/transform-object-assign/ https://babeljs.io/docs/plugins/transform-object-assign/

If using NPM 如果使用NPM

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

I faced the same problem. 我遇到了同样的问题。 I thought I'm safe to use all ES2015+ featues when backed by babel. 我认为在巴贝尔的支持下,我可以安全地使用所有ES2015 +特色。 But as it was mentioned above, babel polyfills only syntax, not functions (Object.assign, Array.includes just to name a few). 但正如上面提到的,babel polyfills只有语法,而不是函数(Object.assign,Array.includes仅举几例)。 For Object.assign I prefer not to use polyfill, but use spread operator. 对于Object.assign,我不想使用polyfill,而是使用spread运算符。 In this case babel actually polyfills Object.assign if not found. 在这种情况下,如果找不到,babel实际上会填充Object.assign。 Take a look at this code: 看看这段代码:

let obj = {a: 1};
let obj2 = {...obj};
let obj3 = Object.assign({}, obj);

It will be tranpiled by babel to: 它将由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);

For spread operator babel tries to used native Object.assign method and use polyfill if it was not found. 对于传播运算符,babel尝试使用本机Object.assign方法,并在未找到时使用polyfill。 But the explicit Object.assign method is left unchanged ¯\\_(ツ)_/¯ 但显式的Object.assign方法保持不变¯\\ _(ツ)_ /¯

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM