我可以设置Javascript对象的类型吗?

时间:2009-12-17 03:37:07

标签: javascript oop types instanceof typeof

我正在尝试使用Javascript的一些更高级的OO功能,遵循Doug Crawford的“超级构造函数”模式。但是,我不知道如何使用Javascript的本机类型系统从我的对象中设置和获取类型。这是我现在的方式:

function createBicycle(tires) {
    var that = {};
    that.tires = tires;
    that.toString = function () {
        return 'Bicycle with ' + tires + ' tires.';
    }
}

如何设置或检索新对象的类型?如果有正确的方法,我不想创建type属性。

有没有办法覆盖我的自定义对象的typeofinstanceof运算符?

5 个答案:

答案 0 :(得分:15)

在收集两个操作数值之后,instanceof运算符在内部使用抽象[[HasInstance]](V)操作,该操作依赖于原型链。

您发布的模式仅包含扩充对象,并且根本不使用原型链。

如果你真的想使用instanceof运算符,你可以将另一个Crockford的技术Prototypal Inheritance超级构造函数结合起来,基本上可以从Bicycle.prototype继承,即使它是一个空对象,也只是为了愚弄instanceof

// helper function
var createObject = function (o) {
  function F() {}
  F.prototype = o;
  return new F();
};

function Bicycle(tires) {
    var that = createObject(Bicycle.prototype); // inherit from Bicycle.prototype
    that.tires = tires;                         // in this case an empty object
    that.toString = function () {
      return 'Bicycle with ' + that.tires + ' tires.';
    };

    return that;
}

var bicycle1 = Bicycle(2);

bicycle1 instanceof Bicycle; // true

更深入的文章:

答案 1 :(得分:3)

如果您这样声明Bicycleinstanceof将有效:

function Bicycle(tires) {
  this.tires = tires;
  this.toString = function () {
    return 'Bicycle with ' + tires + ' tires.';
  }
}

var b = new Bicycle(2);
console.log(b instanceof Bicycle);

答案 2 :(得分:2)

如果您使用的是构造函数,那么比instanceOf更好的解决方案就是:

Object.toType = function(obj) {
  return ({}).toString.call(obj).match(/\s([a-z|A-Z]+)/)[1].toLowerCase();
}


toType({a: 4}); //"object"
toType([1, 2, 3]); //"array"
(function() {console.log(toType(arguments))})(); //arguments
toType(new ReferenceError); //"error"
toType(new Date); //"date"
toType(/a-z/); //"regexp"
toType(Math); //"math"
toType(JSON); //"json"
toType(new Number(4)); //"number"
toType(new String("abc")); //"string"
toType(new Boolean(true)); //"boolean"
toType(new CreateBicycle(2)); //"createbicycle"

解释为什么这是最好的方式,这取决于This帖子。

答案 3 :(得分:1)

仅在Firefox中,您可以使用__proto__属性替换对象的原型。否则,您无法更改已创建的对象的类型,您必须使用new关键字创建新对象。

答案 4 :(得分:0)

  

在我看来,在一个设计合理   类型heirarchy,你不需要知道   单个对象的类型。   但我似乎是少数人   那一点。

     

如果您必须有型号标识,   说清楚。

     

MyClass.prototype.type =“MyClass”;

     

至少可靠且便携   为你的对象。它也适用于   上下文。 DOM对象是另一个   问题,虽然你可以做的事情   

让自己更轻松      

window.type =“window”;

     

等等。

我认为上面引用的是Douglas Crockford写的。