0

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 );

つまり、プロトタイプを持っているか、非ネイティブ型のいずれかからプロトタイプを継承した関数...

4

3 に答える 3

0

関数が拡張された を持たないかどうかを判断するにはprototype、たとえば、単純な関数以上であると想定できる場合、次の関数は を返しfalseます。

   function isPlainFunction(value) {
        if (typeof value !== 'function') {
            return false;
        }

        var own = Object.getOwnPropertyNames(value.prototype);

        if ( own.length >= 2 || ( own.indexOf('constructor') < 0 && own.length >= 1 ) ) {
            return false;
        }

        return Object.getPrototypeOf(value.prototype) === Object.prototype;
    }
于 2013-11-20T00:09:41.287 に答える