2012-02-14 30 views
2

我有在JavaScript創建類的類定義方法:如何解決在JavaScript這個類的定義,以支持instanceof運算符

var Class = function() { 
    var clazz = null, 
    pros = {}; 
    for (var i = 0; i < arguments.length; i++) { 
     var arg = arguments[i]; 
     if (typeof arg == "function") arg = arg.prototype; 
     else { 
      arg.init && (clazz = arg.init, delete arg.init) 
     } 
     for (var p in arg) pros[p] = arg[p]; 
    } 
    clazz.prototype = pros; 
    return clazz; 
}; 

var Person = Class({ 
    init: function(name) { 
     this.name = name; 
    }, 
    say:function(){ 
     console.info(this.name); 
    } 
}); 

var Man = Class(Person, { 
    init: function(name) { 
     Person.apply(this, arguments); 
     this.gender = 'man' 
    } 
}); 

var m = new Man('kk'); 
console.info(m instanceof Man); 
console.info(m instanceof Person); 

但是,它不支持instanceof操作。

任何想法解決它?

+0

這解釋的instanceof是如何工作的:https://developer.mozilla.org/en/JavaScript/Reference/Operators/instanceof – 2012-02-14 11:25:22

+0

或者這裏:http://es5.github.com/#x11.8.6 – 2012-02-14 11:26:25

+0

我讀過這個。我嘗試將'arg = arg.prototype'更改爲'arg = new arg()'。這是行不通的。 – hguser 2012-02-14 11:28:20

回答

3

您應該跟蹤原型鏈以使instanceof正常工作。你目前所做的只是將屬性複製到一個對象中,並將其用作返回函數的原型。因此,ParentMan的父項的信息丟失。

您需要設置原型而不是複製。 由於您需要修改現有對象以設置基礎原型,因此不建議使用__proto__屬性。這裏不能使用Object.create,因爲這會返回一個新的對象。

編輯:很可能沒有__proto__,但你需要的function F招:http://jsfiddle.net/p9pvQ/

var clazz = null, 
    pros = Object.prototype; // root of chain 

for (var i = 0; i < arguments.length; i++) { 
    var arg = arguments[i]; 

    if (typeof arg === "function") { 
     arg = arg.prototype; 
    } else { 
     if(arg.init) { 
      clazz = arg.init; 
      delete arg.init; 
     } 
     var o = arg; 
     arg = (function() { function F() {}; F.prototype = pros; return new F; })(); 
     for(var key in o) arg[key] = o[key]; 
    } 

    pros = arg; 
} 

m屆時將有原型鏈如下:

Class.init // m 
    gender: "man" 
    name: "kk" 
    __proto__: F // Man 
    __proto__: F // Person 
     say: function(){ 
     __proto__: Object // Object.prototype 
     __defineGetter__: function __defineGetter__() { [native code] } 
     __defineSetter__: function __defineSetter__() { [native code] } 
     ... (Object.prototype functions) 
+0

'arg .__ proto__ = pros;'我注意到這行。我不知道這個工作在IE嗎? – hguser 2012-02-14 12:16:57

+0

@hguser:看起來不像。不過,我不知道該如何去做。讓我對此做一些更多的研究。 – pimvdb 2012-02-14 12:19:24

+0

感謝您的關注。實際上它不限於我的代碼。我只想要一個類定義方法,而且我不存在一些無盡的原型鏈。 – hguser 2012-02-14 12:21:57