質問: Object.prototype); ``` このコードの場合はよくわかりません。 hoge.*proto*はtypeof()で確認すると、functionと出てきます。なので組み込みオブジェクトFunctionを元に作られたオブジェクトだと思うのですが、その場合、Function.prototype.*proto*ということになり、これはFunction.prototypeと同じオブジェクトを参照していると思うのですが、これはfalseになります。 なぜObject.prototypeがtrueになるのでしょうか? 組み込みオブジェクトObjectがFunctionから作られたオブジェクトだということはわかっています 教えて下さい
回答: JavaScriptにおいて、関数の継承はこのようになっています。 * **ほとんど全ての関数** <- `%FunctionPrototype%` <- `%ObjectPrototype%` (<- `null`) ``` function hoge(){} console.log(hoge.__proto__ === Function.prototype); // true console.log(hoge.__proto__.__proto__ === Object.prototype); // true console.log(hoge.__proto__.__proto__.__proto__ === null); // true ``` この基本さえ抑えれば、疑問が解決するかと思います。 順に説明していきます。 ほとんど全ての関数 **ほとんど全ての関数**とは、その名の通りJavaScriptにおけるほぼすべての関数を指します。例えば、 * `Number`, `window.alert` のような、もともと用意されている関数 * `var f = function(){};` のような、自分で作成した関数 など、通常使うすべての関数が当てはまります。 %FunctionPrototype% `%FunctionPrototype%`とは、**ほとんど全ての関数**が次に継承している特殊な関数です。 実際のJavaScriptでは`Function.prototype`や`function hoge(){}; hoge.__proto__`などで取得できます。 これが何のために存在するかというと、他の関数たちに関数特有のメソッドを与えるためです。 * `apply()` * `bind()` * `call()` つまり、`%FunctionPrototype%`が存在するために、`func.call();` などが使えるわけですね。 ``` function hoge(){} console.log(hoge.call === Function.prototype.call); // true ... hoge.call は %FunctionPrototype%.call を参照している console.log(hoge.hasOwnProperty("call")); // false ... hoge 自体が call を持っているわけではない ``` %ObjectPrototype% 最後に`%ObjectPrototype%`とは、JavaScriptのほとんどのオブジェクトが継承している特殊なオブジェクトです。 実際のJavaScriptでは`Object.prototype`や`var hoge = {}; hoge.__proto__`などで取得できます。 これが何のために存在するかというと、他のオブジェクトに基本的なメソッドを与えるためです。 * `hasOwnProperty()` * `toString()` ``` var o = {}; console.log(o.toString()); // [object Object] function f(a, b, c){} console.log(f.hasOwnProperty("length")); // true ``` 最初の疑問 最初の疑問に戻りますと、 > > その場合、Function.prototype.protoということになり、これはFunction.prototypeと同じオブジェクトを参照していると思うのですが > > > これが実は違います。`Function.prototype`は確かに関数なのですが、関数でも`%FunctionPrototype%`という特殊な関数を指しています。 つまり、その特殊な関数のプロトタイプは、`%ObjectPrototype% (=Object.prototype)` になるわけです。