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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32148218/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 07:40:20  来源:igfitidea点击:

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

javascriptecmascript-6webpackbabeljs

提问by Collin Allen

I'm attempting to use Object.assign()in an ES6 web app compiled by Babel with webpack, but I'm getting an error:

我试图Object.assign()在 Babel 用 webpack 编译的 ES6 web 应用程序中使用,但出现错误:

Uncaught TypeError: Object.assign is not a function

I'm already using babel-loaderto 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 by importing babel-runtime, but I'd like to understand whyObject.assign()requires more than what babel-loaderperforms — shouldn't babel-loaderpreprocess everything, including Object.assign()?

我已经在使用babel-loader将 ES6 转译为 ES5,所以我所有的其他 ES6 代码都在工作。然而,Object.assign()只有在我也在import "babel-core/polyfill"我的代码库中之后才有效。我看到我也可以通过导入 babel-runtime来解决这个问题,但我想了解为什么Object.assign()需要比babel-loader执行的更多- 不应该babel-loader预处理所有内容,包括Object.assign()?

采纳答案by loganfsmyth

Babel, via babel-loader, transpiles differences in ES6 syntax. Babel on its own does absolutely nothing to add in ES6 standard library functionality (like Object.assign). Loading the polyfill loads a separate polyfill core-jsfor you, but you can load any polyfill you want.

Babel 通过babel-loader,转译 ES6语法中的差异。Babel 本身完全没有添加 ES6 标准库功能(如Object.assign)。加载 polyfill 会core-js为你加载一个单独的 polyfill ,但你可以加载任何你想要的 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. The ES6 features on http://babeljs.io/docs/learn-es2015/each list what standard library functionality are assumed to have been loaded.

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

回答by Breno Ferreira

Object.assign()is a new API that's part of ES6 spec, so it's not implemented in most browsers yet. See: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

Object.assign()是 ES6 规范的一部分的新 API,因此尚未在大多数浏览器中实现。请参阅: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.

因此,当您 import 时babel-core/polyfill,它会为此添加 polyfill 和其他新 API,以便您的 ES6 代码可以使用它们。

babel-loaderis just the transpiler that converts ES6 syntax to ES5 compatible code.

babel-loader只是将 ES6 语法转换为 ES5 兼容代码的转译器。

回答by Velu S Gautam

If you go down to Compatibility you can see IE 11is not supported in both Web and Mobile for object.assign. It also gives you the pollyfill for that.

如果您转到兼容性,您会发现Web 和移动设备都不支持IE 11的 object.assign。它还为您提供了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

如果使用 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

回答by Eugene Karataev

I faced the same problem. I thought I'm safe to use all ES2015+ featues when backed by babel. But as it was mentioned above, babel polyfills only syntax, not functions (Object.assign, Array.includes just to name a few). For Object.assign I prefer not to use polyfill, but use spread operator. In this case babel actually polyfills Object.assign if not found. Take a look at this code:

我遇到了同样的问题。我认为在 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);

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. But the explicit Object.assign method is left unchanged ˉ\_(ツ)_/ˉ

对于扩展运算符,babel 尝试使用原生 Object.assign 方法,如果找不到则使用 polyfill。但是显式的 Object.assign 方法保持不变 ˉ\_(ツ)_/ˉ