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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1919295/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-22 21:53:20  来源:igfitidea点击:

Can I set the type of a Javascript object?

javascriptooptypesinstanceoftypeof

提问by Evan Kroske

I'm trying to use some of the more advanced OO features of Javascript, following Doug Crawford's "super constructor" pattern. However, I don't know how to set and get types from my objects using Javascript's native type system. Here's how I have it now:

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

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

How can I set or retrieve the type of my new object? I don't want to create a typeattribute if there's a right way to do it.

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

Is there a way to override the typeofor instanceofoperators for my custom object?

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

回答by CMS

The instanceofoperator, internally, after both operand values are gather, uses the abstract [[HasInstance]](V)operation, which relies on the prototype chain.

instanceof操作者,在内部,后两个操作数的值是收集,使用抽象[[HasInstance]](V)操作,这依赖于原型链。

The pattern you posted, consists simply on augmenting objects, and the prototype chain is not used at all.

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

If you really want to use the instanceofoperator, you can combine another Crockford's technique, Prototypal Inheritancewith super constructors, basically to inherit from the Bicycle.prototype, even if it's an empty object, only to fool instanceof:

如果你真的想使用instanceof运算符,你可以结合另一个 Crockford 的技术,Prototypal Inheritancewith super constructors,基本上是从 继承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

A more in-depth article:

一篇更深入的文章:

回答by Annie

If you declare Bicyclelike this, instanceofwill work:

如果您这样声明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);

回答by Xeltor

if you're using a constructor, a better solution than instanceOf, would be this :

如果您使用的是构造函数,比 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"

The explanation of WHYit's the best way to do it relies in Thispost.

为什么它是最好的方法的解释依赖于这篇文章。

回答by Tobias Cohen

In Firefox only, you can use the __proto__property to replace the prototype for an object. Otherwise, you cannot change the type of an object that has already been created, you must create a new object using the newkeyword.

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

回答by Upperstage

In my opinion, in a properly designed type heirarchy, you don't need to know the types of the individual objects. But I seem to be in the minority on that point.

If you must have type identification, make it explicit.

MyClass.prototype.type = "MyClass";

It is reliable and portable, at least for your objects. It also works across contexts. DOM objects are another matter, although you can make things easier for yourself with

window.type = "window";

and so on.

在我看来,在正确设计的类型层次结构中,您不需要知道单个对象的类型。但在这一点上我似乎是少数。

如果您必须具有类型标识,请使其明确。

MyClass.prototype.type = "MyClass";

它可靠且便携,至少对于您的对象而言是这样。它也可以跨上下文工作。DOM 对象是另一回事,尽管您可以使用

window.type = "窗口";

等等。

I believe the quote above was written by Douglas Crockford.

我相信上面的引文是由道格拉斯·克罗克福德( Douglas Crockford) 写的。