SafariにおけるgetOwnPropertyNamesの"use strict"下での挙動

  • 5
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

SafariのgetOwnPropertyNamesの引数にFunctionのインスタンスを渡した時の挙動がChromeと違っていたのでメモ。

結論

バグ

"use strict";での挙動

以下のコードでテストしてみる。

"use strict";

function Klass1() {}

Klass1.staticProp = 'staticProp';

var Klass2 = new Function();

Klass2.staticProp = 'staticProp';

var Klass3 = function () {};

Klass3.staticProp = 'staticProp';

console.log(Object.getOwnPropertyNames(Klass1));
console.log(Object.getOwnPropertyNames(Klass2));
console.log(Object.getOwnPropertyNames(Klass3));

console.log(Klass1.name);
// => "Klass1"
console.log(Klass2.name);
// => "anonymous"
console.log(Klass3.name);
// => ""
console.log(Klass1.__proto__ === Function.prototype);
// => true
console.log(Klass2.__proto__ === Function.prototype);
// => true
console.log(Klass3.__proto__ === Function.prototype);
// => true

Safari

console.log(Object.getOwnPropertyNames(Klass1));
// => ["length", "name", "arguments", "caller", "prototype", "staticProp"]
console.log(Object.getOwnPropertyNames(Klass2));
// => ["length", "name", "arguments", "caller", "prototype", "staticProp"]
console.log(Object.getOwnPropertyNames(Klass3));
// => ["length", "name", "arguments", "caller", "prototype", "staticProp"]

Chrome

console.log(Object.getOwnPropertyNames(Klass1));
// => ["length", "name", "prototype", "staticProp"]
console.log(Object.getOwnPropertyNames(Klass2));
// => ["length", "name", "arguments", "caller", "prototype", "staticProp"]
console.log(Object.getOwnPropertyNames(Klass3));
// => ["length", "name", "prototype", "staticProp"]

もちろんどちらの環境でも下のコードは同様にエラーになる。

console.log(Klass.arguments);
// => TypeError
console.log(Klass.caller);
// => TypeError

"use strict";無しでの挙動

どちらもargumentscallerプロパティを含む。

console.log(Object.getOwnPropertyNames(Klass));
// => ["length", "name", "arguments", "caller", "prototype", "staticProp"]
console.log(Klass.arguments);
// => null
console.log(Klass.caller);
// => null

まとめる

SafariではStrictモードでもargumentscallerプロパティが表示される。

ChromeではFunctionのコンストラクタで作成したFunctionのインスタンスではargumentscallerプロパティが表示され、それ以外では表示されない。

ECMA見るとargumentscallerが表示されてしまうのは想定された挙動では無いらしい。

ECMAScript 2015 Language Specification – ECMA-262 6th Edition
16.1 Forbidden Extensions
http://www.ecma-international.org/ecma-262/6.0/index.html#sec-forbidden-extensions