JavaScriptにおいて、関数の継承はこのようになっています。
- ほとんど全ての関数 <-
%FunctionPrototype%
<- %ObjectPrototype%
(<- null
)
javascript
1function hoge(){}
2console.log(hoge.__proto__ === Function.prototype); // true
3console.log(hoge.__proto__.__proto__ === Object.prototype); // true
4console.log(hoge.__proto__.__proto__.__proto__ === null); // true
この基本さえ抑えれば、疑問が解決するかと思います。
順に説明していきます。
##ほとんど全ての関数
ほとんど全ての関数とは、その名の通りJavaScriptにおけるほぼすべての関数を指します。例えば、
Number
, window.alert
のような、もともと用意されている関数
var f = function(){};
のような、自分で作成した関数
など、通常使うすべての関数が当てはまります。
##%FunctionPrototype%
%FunctionPrototype%
とは、ほとんど全ての関数が次に継承している特殊な関数です。
実際のJavaScriptではFunction.prototype
やfunction hoge(){}; hoge.__proto__
などで取得できます。
これが何のために存在するかというと、他の関数たちに関数特有のメソッドを与えるためです。
つまり、%FunctionPrototype%
が存在するために、func.call();
などが使えるわけですね。
javascript
1function hoge(){}
2console.log(hoge.call === Function.prototype.call); // true … hoge.call は %FunctionPrototype%.call を参照している
3console.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)
になるわけです。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。