Можно ли задать тип объекта Javascript?

Я пытаюсь использовать некоторые из более продвинутых функций OO Javascript, следуя шаблону "супер конструктора" Дуга Кроуфорда. Тем не менее, я не знаю, как устанавливать и получать типы из моих объектов с использованием собственной системы Javascript. Вот как это у меня сейчас:

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

Как установить или получить тип моего нового объекта? Я не хочу создавать атрибут type, если есть правильный способ сделать это.

Есть ли способ переопределить операторы typeof или instanceof для моего пользовательского объекта?

Ответы

Ответ 1

Оператор 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

Более подробная статья:

Ответ 2

Если вы объявите Bicycle следующим образом, instanceof будет работать:

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

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

Ответ 3

если вы используете конструктор, лучшее решение, чем 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"

Объяснение ПОЧЕМУ это лучший способ сделать это, полагается в Это сообщение.

Ответ 4

Только в Firefox вы можете использовать свойство __proto__ для замены прототипа для объекта. В противном случае вы не можете изменить тип объекта, который уже был создан, вы должны создать новый объект, используя ключевое слово new.

Ответ 5

По-моему, в правильно спроектированном типа, вам не нужно знать типы отдельных объектов. Но я, кажется, в меньшинстве эта точка.

Если у вас есть идентификация типа, сделайте это явным.

MyClass.prototype.type = "MyClass";

Он надежный и портативный, по крайней мере для ваших объектов. Он также работает контексты. Объектами DOM являются другие материя, хотя вы можете делать вещи проще для себя с помощью

window.type = "window";

и т.д.

Я считаю, что приведенная выше цитата была написана Дуглас Крокфорд.