簡體   English   中英

如何檢查是否在JavaScript類中定義了方法

[英]How can I check whether a method is defined in a JavaScript class

我需要檢查一個類定義是否通過繼承提供,一個特定的方法。 我是否需要前往原型鏈來實現這一目標?

function TestClass(config){
    //NOTE: cannot instantiate class because if config not valid Error is thrown
}
TestClass.prototype.sampleMethod = function(){};

function isDefined(klass){
      console.log(typeof klass.sampleMethod); //'undefined'
      console.log('sampleMethod' in klass); //false
      console.log(klass['sampleMethod']); //undefined

      console.log(typeof klass.prototype.sampleMethod); //'function' ...inheritance?
}

isDefined(TestClass);

我認為問題可能是你不能檢測一個類是否直接實現了什么而不查看類的實例,除非你專門將它的實例分配給新類的原型進行檢查。 請記住,當為類的原型提供屬性sampleMethod時,它是一個表示原型的實例對象,而不是類。 事實上,類在JavaScript中並不像那樣存在。

function TestClass(config){}
TestClass.prototype.sampleMethod = function(){};

function isDefined(klass){
  var holder, _defined = false;
  try{
    holder = new klass({});
    _defined = typeof holder.sampleMethod !== 'undefined'; // does the prototype lookup for you
  }catch(e){
    console.log('Error loading class for reasons other than invalid method.', e)
  }finally{
    return _defined;
  }
}

這是你想要的嗎?

function TestClass(config) {}
TestClass.prototype.sampleMethod = function() {};

function isDefined(klass, method) {
    return (klass && method ?
    function() {
        return !!klass.prototype[method];
    }() : false);
}

這樣做的例子: http//fiddle.jshell.net/Shaz/2kL9A/

是的,您需要檢查原型鏈。

function TestClass(config){}
TestClass.prototype.sampleMethod = function(){};

function TestClass2() {}
TestClass2.prototype = TestClass;

function isDefined(obj, method) {
    if (obj.prototype !== undefined) {
        var methodInPrototype = (method in obj.prototype);
        console.log("Is " + method + " in prototype of " + obj + ": " + methodInPrototype);
        if (methodInPrototype) {
                return true;
        } else {
            isDefined(obj.prototype, method);
        }
    }
    return false;
}

isDefined(TestClass, "sampleMethod");
isDefined(TestClass2, "sampleMethod");
isDefined(TestClass2, "sampleMethod2");

打印:

// Is sampleMethod in prototype of function TestClass(config) {}: true
// Is sampleMethod in prototype of function TestClass2() {}: false
// Is sampleMethod in prototype of function TestClass(config) {}: true
// Is sampleMethod2 in prototype of function TestClass2() {}: false
// Is sampleMethod2 in prototype of function TestClass(config) {}: false

我不明白你為什么要測試一個構造函數,我只是直接測試一個對象,看看它是否有一個特定的方法。

無論如何,加布里埃爾非常接近,但我會做的有點不同:

function MyConstructor(){}
MyConstructor.prototype.sampleMethod = function(){};

// Return true if instances of constructor have method
// Return false if they don't
// Return undefined if new constructor() fails 
function isDefined(constructor, method){
  var temp, defined;
  try {
    temp = new constructor();
    defined = !!(typeof temp[method] == 'function');
  } catch(e) {
    // calling - new constructor - failed
  }
  return defined;
}

var foo;

alert(
  isDefined(MyConstructor, 'sampleMethod')             // Method on MyConstructor.prototype
  + '\n' + isDefined(MyConstructor, 'undefinedMethod') // Not defined
  + '\n' + isDefined(MyConstructor, 'toString')        // Method on Object.prototype
  + '\n' + isDefined(foo, 'foo')                       // foo is not a constructor
);

當然,上述僅適用於通過[[prototype]]的經典原型繼承,在使用模塊模式或類似模式時需要其他東西(即使用閉包的“inhertiance”)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM