Изменение типа объекта в JavaScript - PullRequest
9 голосов
/ 02 июля 2010

У меня есть массив существующих объектов, определенных с помощью JSON.Объекты явно имеют тип Object.Как я могу связать их с пользовательским типом объекта, чтобы дать им определенную функциональность?

Ответы [ 5 ]

12 голосов
/ 02 июля 2010

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

Или, если вас не волнует IE:

var obj = {
    name : "Jeremy"
};

function CustomType() {
    this.name = this.name || "someValue";
    this.greeting = "Hi";
}

CustomType.prototype.sayHi = function() {
    alert(this.greeting + ", " + this.name);
};

obj.__proto__ = CustomType.prototype;
obj.constructor.call(obj);

obj.sayHi();
4 голосов
/ 02 июля 2010

Я не верю, что есть какой-либо способ изменить тип объекта после его создания.К счастью, вам, вероятно, на самом деле не нужно менять класс своих объектов - вы, вероятно, будете удовлетворены, предоставив объектам некоторые новые методы и другие функциональные возможности.(Единственное реальное различие заключается в том, что произойдет, если вы ИЗМЕНИТЕ класс, и большинство людей не изменяет классы во время выполнения кода.)

Я поделюсь примером для вас.Сначала я создам простой объект для представления имеющихся у вас объектов JSON:

var myobj = new Object()
myobj.name = "Fred"

Затем я создам некоторый класс, который вы хотели бы назначить на myobj:

function Speaker() {
    this.speak = function() {
        window.alert("Hello, " + this.name);
    }
}

Этот новый Speaker класс имеет некоторые полезные функции: он может использовать метод speak() для вывода полезной информации:

var s = new Speaker()
s.name = "Sally"
s.speak()

Выполнение, которое дало мне сообщение " Здравствуйте,Салли ».К сожалению, вам не нужен НОВЫЙ объект (например, s) с этой функциональностью, вы хотите, чтобы существующий объект (myobj) имел его.Вот как вы это делаете:

myobj.speak = s.speak

Теперь, когда я выполняю это:

myobj.speak()

Я вижу сообщение " Здравствуйте, Фред ".

Подводя итог: создайте объект, который делает то, что вы хотите.Скопируйте все методы (и любые вспомогательные переменные) в ваш новый объект.За исключением необычного использования наследования, ваш новый объект будет вести себя так, как вам нужно.

3 голосов
/ 17 декабря 2016

Если вам не нужен конструктор, вы можете сделать так:

Object.assign(new CustomType, {});
2 голосов
/ 02 июля 2010

Если вы хотите использовать определенный метод для них, вы можете использовать apply / call.

Или вы можете скопировать методы для вашего пользовательского объекта.

function Object1() {
  this.aValue = "10";
}

function CustomObject() {
  this.customValue = "6";
}

function convertToCustom(obj) {
  var custom = new CustomObject();
  for( var key in obj ) {
    custom[key] = obj[key];
  }
  return custom;
}

var obj = new Object1();
var custom = convertToCustom(obj);

console.log(custom.customValue); // <- 6
console.log(custom.aValue);      // <- 10
1 голос
/ 23 мая 2012

В качестве дополнения к ответу Джереми, вы можете использовать Object.create вместо прямой игры с proto . Вам также понадобится функция «Расширить».

Итак, учитывая пример Джереми, вы можете получить что-то вроде этого:

var obj = {
name : "Jeremy"
};


function CustomType() {
}

CustomType.prototype.init = function(){
    this.name = this.name || "someValue";
    this.greeting = "Hi";
    return this; //let's make it fluent
}

CustomType.prototype.sayHi = function() {
    console.log(this.greeting + ", " + this.name);
};

function extend(obj, props) { 
    for(prop in props) { 
        if(props.hasOwnProperty(prop)) { 
            obj[prop] = props[prop]; 
        } 
    }
    return obj; //let's make it fluent
}

obj = extend(Object.create(CustomType.prototype), obj).init();

obj.sayHi();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...