wake-up-neo.com

Warum benötigt Object.assign () eine Polyfill, wenn der Babel-Loader wird?

Ich versuche, Object.assign() in einer von Babel mit Webpack kompilierten ES6-Web-App zu verwenden, es wird jedoch ein Fehler angezeigt:

Uncaught TypeError: Object.assign is not a function

Ich verwende bereits babel-loader , um ES6 auf ES5 zu transpilieren, daher funktioniert mein anderer ES6-Code. Object.assign() funktioniert jedoch erst, nachdem ich import "babel-core/polyfill" in meiner Codebase gespeichert habe. Ich sehe, dass ich das auch beheben kann indem ich babel-runtime importiere , aber ich würde gerne verstehen, warumObject.assign() mehr erfordert als babel-loader - sollte babel-loader nicht alles vorverarbeiten, einschließlich Object.assign()?

58
Collin Allen

Babel transpiliert über babel-loader Unterschiede in ES6 syntax. Babel allein kann in der ES6-Standardbibliothek (wie Object.assign) absolut nichts hinzufügen. Wenn Sie den Polyfill laden, wird ein separater Polyfill core-js für Sie geladen. Sie können jedoch auch einen beliebigen Polyfill laden.

Selbst bei einigen Syntaxkonvertierungen sind zum Laden bestimmte Polyfill-Funktionen erforderlich, da einige Syntax auf Algorithmen und Verhalten basiert, die in Bibliothekscode implementiert sind. Die ES6-Funktionen auf http://babeljs.io/docs/learn-es2015/ listen jeweils auf, welche Standard-Bibliotheksfunktionen als geladen gelten.

53
loganfsmyth

Object.assign() ist eine neue API, die Teil der ES6-Spezifikation ist und daher in den meisten Browsern noch nicht implementiert ist. Siehe: https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

Wenn Sie also babel-core/polyfill importieren, werden diesem und anderen neuen APIs Polyfills hinzugefügt, sodass Ihr ES6-Code sie verwenden kann.

babel-loader ist nur der Transpiler, der die ES6-Syntax in ES5-kompatiblen Code umwandelt.

11
Breno Ferreira

Wenn Sie zu Kompatibilität gehen, können Sie sehen, dass IE 11 sowohl in Web als auch in Mobile für object.assign nicht unterstützt wird. Es gibt Ihnen auch die Pollyfill dafür.

https://developer.mozilla.org/de/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;
  };
 }

Bei Verwendung von Babel

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

Bei Verwendung von NPM

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

8
Velu S Gautam

Ich hatte das gleiche Problem. Ich dachte, ich könnte alle ES2015 + -Features verwenden, wenn sie von Babel unterstützt werden. Wie oben erwähnt, enthält babel polyfills nur die Syntax, nicht die Funktionen (Object.assign, Array.includes, um nur einige zu nennen) .. Für Object.assign benutze ich lieber kein Polyfill, sondern den Spread-Operator. In diesem Fall füllt babel eigentlich Object.assign, wenn es nicht gefunden wird. Sehen Sie sich diesen Code an:

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

Es wird von Babel zu tranpiled:

"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);

Für den Spread-Operator versucht babel, die native Object.assign-Methode zu verwenden und polyfill zu verwenden, falls er nicht gefunden wurde .. Die explizite Object.assign-Methode bleibt jedoch ¯\_ (ツ) _/¯ unverändert

0
Eugene Karataev