質問: { sayHello: sayHelloShared, name: 'Alice' }; alice.sayHello(); sayHelloShared(); 上記をchromeのconsoleで確認したところ、 Hello, I'm Alice Hello, I'm CodePen と出ました。 また、2行目の「this.name」を「this」にして同様に確認したところ、 Hello, I'm [object Object] Hello, I'm [object Window] と出ました。 javascriptにおいてthisは、当該関数のobjectを参照するはずですが、 ・CodePen ・[object Object] ・[object Window] は具体的に何を意味しているのでしょうか?
回答: ### String 型への変換 ``` "Hello, I'm " + this; ``` 文字列リテラルと連結する事で `this` は `String` 型に変換されます。 この時、内部的には `Object.prototype.toString` が呼び出されます。 ### ES5.1 の Object.prototype.toString ES5.1 の `Object.prototype.toString` は次の演算結果を返します。 ``` '[object ' + [[Class]] + ']'; // ES5.1 ``` 内部プロパティ `[[Class]]` は読み取り専用であり、ユーザ定義する事は出来ません。 オブジェクト初期化子で宣言されたオブジェクトの `[[Class]]` は `Object` です。 ブラウザにおけるグローバルオブジェクトの `[[Class]]` は `Window` です。 ``` /** * グローバルコード */ console.log(this.toString()); // "[object Window]" console.log({}.toString()); // "[object Object]" ``` * 15.2.4.2 Object.prototype.toString - ECMA-262 Edition 5.1 ### ES6 の Object.prototype.toString ES6 の `Object.prototype.toString` は次の演算結果を返します。 ``` '[object ' + @@toStringTag + ']'; // ES6 ``` `@@toStringTag` は `Symbol.toStringTag` で参照可能なプロパティです。 `new Object`, `new Array` 等のビルトインオブジェクトが返す値は ES5 の `[[Class]]` と変わりませんが、ES5 と違って `@@toStringTag` を書き換えることが可能です。 ``` function Sample () {} Sample.prototype[Symbol.toStringTag] = 'Sample'; console.log(new Sample().toString()); // "[object Sample]" ``` * 19.1.3.6 Object.prototype.toString – ECMA-262 6th Edition Re: rralmccoy さん