【问题标题】:Why does Object.assign() require a polyfill when babel-loader is being used?为什么在使用 babel-loader 时 Object.assign() 需要 polyfill?
【发布时间】:2015-08-21 19:46:46
【问题描述】:

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

Uncaught TypeError: Object.assign is not a function

我已经在使用babel-loader 将 ES6 转换为 ES5,所以我所有的其他 ES6 代码都可以正常工作。然而,Object.assign() 仅在我的代码库中也有import "babel-core/polyfill" 之后才有效。我看到我也可以修复这个by importing babel-runtime,但我想了解为什么Object.assign() 需要的不仅仅是babel-loader 执行的功能——babel-loader 不应该预处理所有内容,包括@ 987654332@?

【问题讨论】:

  • 只是给未来读者的一个提示:根据the docs,在编写此问题时称为“babel-core/polyfill”的 polyfill 现在是“babel-polyfill”。跨度>
  • 在 v7 中现在只是 @babel/polyfill
  • 从 Babel 7.4.0 开始,babel/polyfill 已被弃用,取而代之的是直接包含 core-js/stable(用于填充 ECMAScript 功能)和 regenerator-runtime/runtime(需要使用转译生成器函数):跨度>

标签: javascript ecmascript-6 webpack babeljs


【解决方案1】:

Babel,通过babel-loader,转译ES6 语法中的差异。 Babel 本身绝对不会添加 ES6 标准库功能(如 Object.assign)。加载 polyfill 会为你加载一个单独的 polyfill core-js,但你可以加载任何你想要的 polyfill。

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      如果您进入兼容性,您会看到 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

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          猜你喜欢
          • 2020-08-30
          • 2018-09-12
          • 2016-07-11
          • 2019-06-06
          • 1970-01-01
          • 2017-11-26
          • 2023-02-19
          • 2015-04-23
          • 2018-07-29
          相关资源
          最近更新 更多