LoginSignup
3
2

More than 5 years have passed since last update.

babel-polyfillによって使用可能になる処理まとめ・Object編

Last updated at Posted at 2018-05-19

こちらのObject編。

Object.create() ES6

Object.create() メソッドは、指定したプロトタイプオブジェクトおよびプロパティを持つ、新たなオブジェクトを生成します。

// Shape - superclass
function Shape() {
  this.x = 0;
  this.y = 0;
}

// superclass method
Shape.prototype.move = function(x, y) {
  this.x += x;
  this.y += y;
  console.info('Shape moved.');
};

// Rectangle - subclass
function Rectangle() {
  Shape.call(this); // call super constructor.
}

// subclass extends superclass
Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;

var rect = new Rectangle();

console.log('Is rect an instance of Rectangle?', rect instanceof Rectangle);// true
console.log('Is rect an instance of Shape?', rect instanceof Shape);// true
rect.move(1, 1); // Outputs, 'Shape moved.'

Object.defineProperty() ES6

指定されたオブジェクトに新しいプロパティを定義したり、既存のプロパティを変更したりします。戻り値は指定されたオブジェクトがそのまま返ります。

// __proto__ を使うやり方
var obj = {};
var descriptor = Object.create(null); // 意図しないキーの継承を防止します。
// デフォルトの挙動により、継承不能、変更不能、書換不能なプロパティとなります。
descriptor.value = 'static';
Object.defineProperty(obj, 'key', descriptor);

// 明示的に指定するやり方
Object.defineProperty(obj, 'key', {
  enumerable: false,
  configurable: false,
  writable: false,
  value: 'static'
});

// 同じ設定を持つディスクリプタを使い回すやり方
function withValue(value) {
  var d = withValue.d || (
    withValue.d = {
      enumerable: false,
      writable: false,
      configurable: false,
      value: null
    }
  );
  d.value = value;
  return d;
}
// このように使います。
Object.defineProperty(obj, 'key', withValue('static'));

// freeze() が使えるなら、Object.prototype にプロパティ(value, get, set, enumerable, writable, configurable)が
// 追加されたり削除されたりするのを阻止するやり方もあります。
// (訳注:かなり粗暴な振る舞いだと思います...)
(Object.freeze || Object)(Object.prototype);

Object.defineProperties() ES6

Object.defineProperties() メソッドは、オブジェクトに直接新しいプロパティを定義し、あるいは既存のプロパティを変更して、そのオブジェクトを返します。

var obj = {};
Object.defineProperties(obj, {
  'property1': {
    value: true,
    writable: true
  },
  'property2': {
    value: 'Hello',
    writable: false
  }
  // etc. etc.
});

Object.getOwnPropertyDescriptor() ES6

与えられたオブジェクト自身のプロパティ (すなわちオブジェクトが直接提供するプロパティであり、オブジェクトのプロトタイプチェインを伝って提供されるプロパティではありません) の、プロパティディスクリプタを返します。

var o, d;

o = { get foo() { return 17; } };
d = Object.getOwnPropertyDescriptor(o, "foo");
// d is { configurable: true, enumerable: true, get: /*the getter function*/, set: undefined }

o = { bar: 42 };
d = Object.getOwnPropertyDescriptor(o, "bar");
// d is { configurable: true, enumerable: true, value: 42, writable: true }

o = {};
Object.defineProperty(o, "baz", { value: 8675309, writable: false, enumerable: false });
d = Object.getOwnPropertyDescriptor(o, "baz");
// d is { value: 8675309, writable: false, enumerable: false, configurable: false }

Object.getOwnPropertyDescriptors() ES7

Object.getOwnPropertyDescriptors() メソッドは、指定したオブジェクトのすべてのプロパティディスクリプタを返します。

Object.create(
  Object.getPrototypeOf(obj), 
  Object.getOwnPropertyDescriptors(obj) 
);

Object.getPrototypeOf() ES6

Object.getPrototypeOf() メソッドは指定したオブジェクトのプロトタイプ (要するに内部プロパティ[[Prototype]] の値)を返します。

var proto = {};
var obj = Object.create(proto);
Object.getPrototypeOf(obj) === proto; // true

Object.keys() ES6

Object.keys() メソッドは、与えられたオブジェクト自身に存在する列挙可能なプロパティの配列を for...in ループで提供されるものと同じ順番で返します (for-in ループとの違いは、for-in ループではプロトタイプチェインのプロパティも列挙することです)。

// 単純な配列
var arr = ['a', 'b', 'c'];
console.log(Object.keys(arr)); // console: ['0', '1', '2']

// オブジェクトのような配列
var obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.keys(obj)); // console: ['0', '1', '2']

// キーの順序がランダムなオブえジェクトのような配列
var anObj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.keys(anObj)); // console: ['2', '7', '100']

// getFoo は列挙可能ではないプロパティ
var myObj = Object.create({}, {
  getFoo: {
    value: function () { return this.foo; }
  } 
});
myObj.foo = 1;
console.log(Object.keys(myObj)); // console: ['foo']

Object.getOwnPropertyNames() ES6

与えられたオブジェクトで発見されたすべてのプロパティ (列挙可能・不可能を問わず) の配列を返します。

var arr = ['a', 'b', 'c'];
console.log(Object.getOwnPropertyNames(arr).sort()); 
// ["0", "1", "2", "length"] と出力されます

// Array-like object
var obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.getOwnPropertyNames(obj).sort()); 
// ["0", "1", "2"] と出力されます

// Array.forEach を使ったプロパティと値の出力
Object.getOwnPropertyNames(obj).forEach(
  function (val, idx, array) {
  console.log(val + ' -> ' + obj[val]);
  }
);
// 出力結果
// 0 -> a
// 1 -> b
// 2 -> c

// 列挙不可能なプロパティ
var my_obj = Object.create({}, {
  getFoo: {
    value: function() { return this.foo; },
    enumerable: false
  }
});
my_obj.foo = 1;

console.log(Object.getOwnPropertyNames(my_obj).sort()); 
// ["foo", "getFoo"] と出力されます

Object.freeze() ES6

オブジェクトを凍結します: これは、新しいプロパティの追加、既存のプロパティの削除、既存のプロパティやプロパティの列挙可否、設定変更可否、書き込み可否の変更を抑制します。本質的には、オブジェクトを実質的に不変にします。このメソッドは凍結されたオブジェクトを返します。

var obj = {
  prop: function (){},
  foo: "bar"
};

// 新しいプロパティは追加でき、既存のプロパティは変更や削除ができます
obj.foo = "baz";
obj.lumpy = "woof";
delete obj.prop;

var o = Object.freeze(obj);

assert(Object.isFrozen(obj) === true);

// ここではすべての変更が失敗します
obj.foo = "quux"; // 暗黙的に何も行われません
obj.quaxxor = "the friendly duck"; // 暗黙的にプロパティは追加されません

// また、strict モードではこれらの試みに対して TypeErrors が発生します
function fail(){
  "use strict";
  obj.foo = "sparky"; // TypeError が発生
  delete obj.quaxxor; // TypeError が発生
  obj.sparky = "arf"; // TypeError が発生
}

fail();

// Object.defineProperty を用いる変更も失敗します
Object.defineProperty(obj, "ohai", { value: 17 }); // TypeError が発生
Object.defineProperty(obj, "foo", { value: "eit" }); // TypeError が発生

Object.seal() ES6

オブジェクトを封印して、新しいオブジェクトを追加することやすべての既存のプロパティを設定変更不可にすることを抑制します。現存するプロパティの値は、書き込み可能である限り変更できます。

var obj = {
    prop: function () {},
    foo: "bar"
  };

// 新しいプロパティは追加でき、既存のプロパティは変更や削除ができます
obj.foo = "baz";
obj.lumpy = "woof";
delete obj.prop;

var o = Object.seal(obj);

assert(o === obj);
assert(Object.isSealed(obj) === true);

// 封印されたオブジェクトで、プロパティの値の変更は依然としてできます
obj.foo = "quux";

// しかし、データプロパティからアクセサプロパティの変換やその逆はできません
Object.defineProperty(obj, "foo", { get: function() { return "g"; } }); // TypeError が発生

// プロパティの値の変更を除き、あらゆる変更が失敗します
obj.quaxxor = "the friendly duck"; // 暗黙的にプロパティは追加されません
delete obj.foo; // 暗黙的にプロパティは削除されません

// また、strict モードではこれらの試みに対して TypeErrors が発生します
function fail() {
  "use strict";
  delete obj.foo; // TypeError が発生
  obj.sparky = "arf"; // TypeError が発生
}
fail();

// Object.defineProperty を用いて追加しようとしてもエラーが発生します
Object.defineProperty(obj, "ohai", { value: 17 }); // TypeError が発生
Object.defineProperty(obj, "foo", { value: "eit" }); // TypeError が発生

Object.preventExtensions() ES6

// Object.preventExtensions は拡張不可能にしたオブジェクトを返します
var obj = {};
var obj2 = Object.preventExtensions(obj);
assert(obj === obj2);

// 既定でオブジェクトは拡張可能です
var empty = {};
assert(Object.isExtensible(empty) === true);

// この性質は変更できます
Object.preventExtensions(empty);
assert(Object.isExtensible(empty) === false);

// 拡張不可能なオブジェクトに新しいプロパティを追加する際、Object.defineProperty でエラーが発生します
var nonExtensible = { removable: true };
Object.preventExtensions(nonExtensible);
Object.defineProperty(nonExtensible, "new", { value: 8675309 }); // TypeError が発生

// strict mode では、拡張不可能なオブジェクトに新たなプロパティを追加しようとすると TypeError が発生します
function fail()
{
  "use strict";
  nonExtensible.newProperty = "FAIL"; // TypeError が発生
}
fail();

// 拡張機能 (__proto__ (これは廃止されました。代わりに Object.getPrototypeOf を用いてください) をサポートするエンジンに限る): 拡張不可能なオブジェクトのプロトタイプは不変になります
var fixed = Object.preventExtensions({});
fixed.__proto__ = { oh: "hai" }; // TypeError が発生

Object.isFrozen() ES6

オブジェクトが凍結されているかを判定します。

// 新しいオブジェクトは拡張可能であるので、凍結されていません
assert(Object.isFrozen({}) === false);

// 拡張可能ではない空のオブジェクトは、他に何もしなくても凍結されています
var vacuouslyFrozen = Object.preventExtensions({});
assert(Object.isFrozen(vacuouslyFrozen) === true);

// プロパティをひとつ持つ新しいオブジェクトも拡張可能であり、それゆえ凍結されていません
var oneProp = { p: 42 };
assert(Object.isFrozen(oneProp) === false);

// オブジェクトを拡張不可にしても、それは凍結されません
// なぜなら、まだプロパティが設定変更可能 (かつ書き込み可能) であるからです
Object.preventExtensions(oneProp);
assert(Object.isFrozen(oneProp) === false);

// ...しかしプロパティを削除すると、そのオブジェクトは他に何もしなくても凍結されます
delete oneProp.p;
assert(Object.isFrozen(oneProp) === true);

// 書き込み不可であるが設定変更可能なプロパティを持つ、拡張不可のオブジェクトは、凍結されていません
var nonWritable = { e: "plep" };
Object.preventExtensions(nonWritable);
Object.defineProperty(nonWritable, "e", { writable: false }); // 書き込み不可にします
assert(Object.isFrozen(nonWritable) === false);

// プロパティを設定変更不可にすると、オブジェクトは凍結されます
Object.defineProperty(nonWritable, "e", { configurable: false }); // 設定変更不可にします
assert(Object.isFrozen(nonWritable) === true);

// 設定変更不可であるが書き込み可能なプロパティを持つ、拡張不可のオブジェクトは、やはり凍結されていません
var nonConfigurable = { release: "the kraken!" };
Object.preventExtensions(nonConfigurable);
Object.defineProperty(nonConfigurable, "release", { configurable: false });
assert(Object.isFrozen(nonConfigurable) === false);

// プロパティを書き込み不可にすると、オブジェクトは凍結されます
Object.defineProperty(nonConfigurable, "release", { writable: false });
assert(Object.isFrozen(nonConfigurable) === true);

// 設定変更可能なアクセサプロパティを持つ拡張不可のオブジェクトは、凍結されていません
var accessor = { get food() { return "yum"; } };
Object.preventExtensions(accessor);
assert(Object.isFrozen(accessor) === false);

// ...しかしプロパティを設定変更不可にすると、オブジェクトは凍結されます
Object.defineProperty(accessor, "food", { configurable: false });
assert(Object.isFrozen(accessor) === true);

// なお、オブジェクトを凍結するもっとも簡単な方法は、Object.freeze を呼び出すことです
var frozen = { 1: 81 };
assert(Object.isFrozen(frozen) === false);
Object.freeze(frozen);
assert(Object.isFrozen(frozen) === true);

// 定義によると、凍結されたオブジェクトは拡張不可です
assert(Object.isExtensible(frozen) === false);

// また、凍結されたオブジェクトは封印されています
assert(Object.isSealed(frozen) === true);

Object.isSealed() ES6

オブジェクトが封印されているかを判定します。

// 既定でオブジェクトは封印されていません
var empty = {};
assert(Object.isSealed(empty) === false);

// 空のオブジェクトを拡張不可にすると、そのまま封印状態になります
Object.preventExtensions(empty);
assert(Object.isSealed(empty) === true);

// 空でないオブジェクトでは、そのプロパティをすべて設定変更不可にしない限り上記と同じにはなりません
var hasProp = { fee: "fie foe fum" };
Object.preventExtensions(hasProp);
assert(Object.isSealed(hasProp) === false);

// そこですべてのプロパティを設定変更不可にすると、オブジェクトは封印状態になります
Object.defineProperty(hasProp, "fee", { configurable: false });
assert(Object.isSealed(hasProp) === true);

// オブジェクトを封印する最も簡単な方法は、もちろん Object.seal です
var sealed = {};
Object.seal(sealed);
assert(Object.isSealed(sealed) === true);

// 封印されたオブジェクトはその定義により、拡張できません
assert(Object.isExtensible(sealed) === false);

// 封印されたオブジェクトは凍結されているかもしれませんが、必ずしもそうではありません
assert(Object.isFrozen(sealed) === true); // すべてのプロパティが書き込み不能でもあります

var s2 = Object.seal({ p: 3 });
assert(Object.isFrozen(s2) === false); // "p" は依然書き込み可能です

var s3 = Object.seal({ get p() { return 0; } });
assert(Object.isFrozen(s3) === true); // アクセサプロパティでは設定変更が可能かという事柄だけになります

Object.isExtensible() ES6

オブジェクトが拡張可能であるかどうか(新しいプロパティを追加する事が出来るか否か)を決定します。

// 新規のオブジェクトは拡張可能
var empty = {};
assert(Object.isExtensible(empty) === true);

// その設定は変える事が可能
Object.preventExtensions(empty);
assert(Object.isExtensible(empty) === false);

// seal メソッドで封印されたオブジェクトは拡張不可と定義される
var sealed = Object.seal({});
assert(Object.isExtensible(sealed) === false);

// freeze メソッドで凍結されたオブジェクトも拡張不可と定義される
var frozen = Object.freeze({});
assert(Object.isExtensible(frozen) === false);

Object.assign() ES6

一つ以上の ソース オブジェクトから、直接所有で (own) 列挙可能な (enumerable) すべてのプロパティの値を、ターゲット オブジェクトへコピーします。戻り値はターゲット オブジェクトです。

var obj = { a: 1 };
var copy = Object.assign({}, obj);
console.log(copy); // { a: 1 }

Object.is() ES6

Object.is() メソッドは 2 つの値の同一性を判定します。

Object.is('foo', 'foo');     // true
Object.is(window, window);   // true

Object.is('foo', 'bar');     // false
Object.is([], []);           // false

var test = { a: 1 };
Object.is(test, test);       // true

Object.is(null, null);       // true

// 特殊なケース
Object.is(0, -0);            // false
Object.is(-0, -0);           // true
Object.is(NaN, 0/0);         // true

Object.setPrototypeOf() ES6

Object.setPrototypeOf() メソッドは指定されたオブジェクトのプロトタイプ(例えば内部の [[Prototype]] プロパティ)を、別のオブジェクトまたは null に設定します。

var dict = Object.setPrototypeOf({}, null);

Object.prototype.toString() ES6

オブジェクトを表す文字列を返します。

var o = new Object();
o.toString(); // [object Object] を返す

Object.values() ES7

Object.values() メソッドは引数に与えたオブジェクトが所有する列挙可能なプロパティの値からなる配列を返します。配列要素の順序は for...in ループによる順序と同じです(両者の違いとして、for-in ループではその上プロトタイプチェーン内のプロパティも列挙されます)。

var obj = { foo: "bar", baz: 42 };
console.log(Object.values(obj)); // ['bar', 42]

// 配列様オブジェクト
var obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.values(obj)); // ['a', 'b', 'c']

// ランダムなキー順序を持つ配列様オブジェクト
var an_obj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.values(an_obj)); // ['b', 'c', 'a']

// 列挙可能でないプロパティ getFoo がある
var my_obj = Object.create({}, { getFoo: { value: function() { return this.foo; } } });
my_obj.foo = "bar";
console.log(Object.values(my_obj)); // ['bar']

// オブジェクトでない引数はオブジェクトへと型強制されます
console.log(Object.values("foo")); // ['f', 'o', 'o']

Object.entries() ES7

Object.entries() メソッドは、引数に与えたオブジェクトが所有する、列挙可能なプロパティの組 [key, value] からなる配列を返します。配列要素の順序は for...in ループによる順序と同じです(両者の違いとして、for-in ループではその上プロトタイプチェーン内のプロパティも列挙されます)。

var obj = { foo: "bar", baz: 42 };
console.log(Object.entries(obj)); // [ ['foo', 'bar'], ['baz', 42] ]

// 配列様オブジェクト
var obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.entries(obj)); // [ ['0', 'a'], ['1', 'b'], ['2', 'c'] ]

// ランダムなキー順序を持つ配列様オブジェクト
var an_obj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.entries(an_obj)); // [ ['2', 'b'], ['7', 'c'], ['100', 'a'] ]

// 列挙可能でないプロパティ getFoo がある
var my_obj = Object.create({}, { getFoo: { value: function() { return this.foo; } } });
my_obj.foo = "bar";
console.log(Object.entries(my_obj)); // [ ['foo', 'bar'] ]

// オブジェクトでない引数はオブジェクトへと型強制されます
console.log(Object.entries("foo")); // [ ['0', 'f'], ['1', 'o'], ['2', 'o'] ]

Object.prototype.__defineGetter__() ES7

非推奨
この機能は Web 標準から削除されました。まだサポートしているプラウザーがあるかもしれませんが、ゆくゆくはなくなるものです。新旧にかかわらず、プロジェクトでの使用をやめてください。この機能を使用するページ、Web アプリはいつ動かなくなってもおかしくありません。

Object.prototype.__defineSetter__() ES7

非推奨
この機能は Web 標準から削除されました。まだサポートしているプラウザーがあるかもしれませんが、ゆくゆくはなくなるものです。新旧にかかわらず、プロジェクトでの使用をやめてください。この機能を使用するページ、Web アプリはいつ動かなくなってもおかしくありません。

Object.prototype.__lookupGetter__() ES7

非推奨
この機能は Web 標準から削除されました。まだサポートしているプラウザーがあるかもしれませんが、ゆくゆくはなくなるものです。新旧にかかわらず、プロジェクトでの使用をやめてください。この機能を使用するページ、Web アプリはいつ動かなくなってもおかしくありません。

Object.prototype.__lookupSetter__() ES7

非推奨
この機能は Web 標準から削除されました。まだサポートしているプラウザーがあるかもしれませんが、ゆくゆくはなくなるものです。新旧にかかわらず、プロジェクトでの使用をやめてください。この機能を使用するページ、Web アプリはいつ動かなくなってもおかしくありません。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2