web-dev-qa-db-ja.com

babel-loaderが使用されているときにObject.assign()がポリフィルを必要とするのはなぜですか?

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"を実行した後にのみ機能します。私もこれを修正できることがわかります babel-runtimeをインポートすることで ですが、理解したいのですがwhyObject.assign()は、babel-loaderが実行する以上のものを必要とします— babel-loaderObject.assign()を含むすべてを前処理するべきではありませんか?

60
Collin Allen

Babelは、babel-loaderを介して、ES6の違いを変換しますsyntax。 Babel自体は、ES6標準ライブラリ機能(Object.assignなど)に追加することはまったくありません。ポリフィルをロードすると、別のポリフィル core-js がロードされますが、任意のポリフィルをロードできます。

一部の構文は、ライブラリコードに実装されたアルゴリズムと動作に依存するため、特定のポリフィル機能がロードに依存している場合もあります。 http://babeljs.io/docs/learn-es2015/ のES6機能は、各標準ライブラリ機能がロードされていると想定されるものをリストします。

55
loganfsmyth

Object.assign()はES6仕様の一部である新しいAPIであるため、ほとんどのブラウザーにはまだ実装されていません。参照: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

したがって、babel-core/polyfillをインポートすると、これにポリフィルが追加され、ES6コードがそれらを使用できるように、他の新しいAPIが追加されます。

babel-loaderは、ES6構文をES5互換コードに変換する単なるトランスパイラーです。

12
Breno Ferreira

互換性を確認すると、IE 11はobject.assignのWebとモバイルの両方でサポートされていません。また、そのための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

9
Velu S Gautam

私は同じ問題に直面しました。バベルに裏付けられたES2015 +のすべての機能を使用しても安全だと思いました。しかし、前述したように、babelは関数ではなく構文のみをポリフィルします(Object.assign、Array.includesはほんの数例です)。 Object.assignの場合、ポリフィルは使用せず、スプレッド演算子を使用します。この場合、babelは実際にObject.assignが見つからない場合にポリフィルします。このコードを見てください:

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

バベルによって次のように変換されます。

"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メソッドを使用しようとし、ポリフィルが見つからない場合は使用します。ただし、明示的なObject.assignメソッドは変更されません¯\ _(ツ)_ /¯

1
Eugene Karataev