web-dev-qa-db-fra.com

Pourquoi Object.assign () requiert-il un polyfill lorsque babel-loader est utilisé?

J'essaie d'utiliser Object.assign() dans une application Web ES6 compilée par Babel avec Webpack, mais je reçois une erreur:

Uncaught TypeError: Object.assign is not a function

J'utilise déjà babel-loader pour transpiler ES6 à ES5, de sorte que tous mes autres codes ES6 fonctionnent. Cependant, Object.assign() ne fonctionne qu'après que j'ai aussi import "babel-core/polyfill" dans ma base de code. Je vois que je peux aussi résoudre ce problème en important babel-runtime , mais j'aimerais comprendre pourquoi Object.assign() nécessite plus que ce que babel-loader effectue - ne devrait pas babel-loader tout prétraiter, y compris Object.assign()?

58
Collin Allen

Babel, via babel-loader, transcrit les différences entre ES6 syntax. Babel seul ne fait absolument rien à ajouter aux fonctionnalités de la bibliothèque standard ES6 (comme Object.assign). Le chargement du polyfill charge un polyfill core-js séparé pour vous, mais vous pouvez charger le polyfill de votre choix.

Même certaines conversions de syntaxe reposent sur des fonctionnalités polyfill spécifiques pour être chargées, certaines syntaxes reposant sur des algorithmes et des comportements implémentés dans le code de bibliothèque. Les fonctionnalités de ES6 sur http://babeljs.io/docs/learn-es2015/ répertorient les fonctionnalités de bibliothèque standard supposées avoir été chargées.

53
loganfsmyth

Object.assign() est une nouvelle API qui fait partie de la spécification ES6. Elle n'est donc pas encore implémentée dans la plupart des navigateurs. Voir: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

Ainsi, lorsque vous importez babel-core/polyfill, il ajoute des polyfill à cela, ainsi qu'à d'autres nouvelles API, afin que votre code ES6 puisse les utiliser.

babel-loader est simplement le transpiler qui convertit la syntaxe ES6 en code compatible ES5.

11
Breno Ferreira

Si vous allez dans Compatibilité, vous constaterez que IE 11 n'est pas pris en charge par Web et par Mobile pour object.assign. Cela vous donne également le pollyfill pour cela.

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;
  };
 }

Si vous utilisez Babel

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

Si vous utilisez NPM

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

8
Velu S Gautam

J'ai rencontré le même problème. Je pensais que je pouvais utiliser toutes les fonctionnalités d'ES2015 + avec Babel. Mais comme il a été mentionné ci-dessus, babel ne polyfille que la syntaxe et non les fonctions (Object.assign, Array.includes pour n'en nommer que quelques-unes) . Dans ce cas, babel polyfille Object.assign s'il n'est pas trouvé. Jetez un oeil à ce code:

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

Babel transmettra ce message à:

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

Pour l'opérateur de propagation, babel essaie d'utiliser la méthode native Object.assign et d'utiliser polyfill si elle n'a pas été trouvée . Mais la méthode explicite Object.assign reste inchangée

0
Eugene Karataev