javascript の関数が、単純な単純な (匿名の) 関数であるか、コンストラクター (プロトタイプを持つ関数) であるかを判断しようとしています。これまでのところ、次の関数を考え出しました。
function isPlainFunction(value) {
var own = Object.getOwnPropertyNames(value.prototype),
ctorIndex = own.indexOf('constructor');
if ( ctorIndex !== -1 ) {
own.splice( ctorIndex, 1);
}
if (own.length) {
return false;
}
// walk prototype chain
var proto = Object.getPrototypeOf(value.prototype);
if (proto === Object.prototype) {
return true;
}
return isPlainFunction(proto);
}
私は ES5 (node.js) のみをターゲットにしていますが、これがすべてのエッジ ケースをカバーしているかどうか、またはこの件に関してまだ見つかっていないものがあるかどうかはわかりません。
私は(大まかに)次のテストケースを念頭に置いています:
assert.ok( isPlainFunction(function(){}) );
var bar = function(){};
bar.prototype = { get one(){ return 1 } };
assert.equal( isPlainFunction(bar), false );
var foo = function(){};
foo.prototype = Object.create( bar );
assert.equal( isPlainFunction(bar), false );
つまり、プロトタイプを持っているか、非ネイティブ型のいずれかからプロトタイプを継承した関数...