【问题标题】:Changing an Object's Type in JavaScript在 JavaScript 中更改对象的类型
【发布时间】:2011-03-11 04:19:44
【问题描述】:

我有一个用 JSON 定义的现有对象数组。对象显然属于 Object 类型。如何将它们与自定义对象类型相关联以赋予它们特定功能?

【问题讨论】:

  • 如果那个对象有额外的属性/方法,你还需要什么?你能举个例子吗?
  • .. 我的意思是,您是否已经定义了此类自定义对象类型,或者您想知道如何做?

标签: javascript javascript-objects


【解决方案1】:

我不相信有任何方法可以在创建对象后更改其类型。幸运的是,您可能实际上不需要更改对象的类——您可能会对为对象提供一些新方法和其他功能感到满意。 (唯一真正的区别是如果您更改了类会发生什么,并且大多数人不会在代码运行时更改类。)

我会为你举一个例子。首先,我将创建一个简单的对象来表示您拥有的 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()

执行给了我消息“Hello, Sally”。不幸的是,您不希望新对象(如s)具有此功能,而是希望现有对象(myobj)拥有它。这样做的方法如下:

myobj.speak = s.speak

现在当我执行这个时:

myobj.speak()

我看到消息“你好,Fred”。

总结:创建一个对象,做你想做的事。将所有方法(和任何辅助变量)复制到新对象中。除了一些不寻常的继承用途外,这将使您的新对象按预期运行。

【讨论】:

    【解决方案2】:

    如果你想对它们使用特定的方法,你可以使用 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
    

    【讨论】:

      【解决方案3】:

      适用于所有浏览器的方式是使用您想要的属性和方法来扩充数组中的每个项目,或者将对象传递给构造函数并基于旧对象的属性和方法创建一个新对象。

      或者如果你不关心 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();
      

      【讨论】:

      • 我确实关心 IE,我接受了您的建议,创建了一个修改传入对象并将其返回给调用者的方法。我已经习惯了在 Perl 中使用“bless”并且能够随心所欲地修改对象。
      【解决方案4】:

      作为对 Jeremy 回答的补充,您可以使用 Object.create 而不是直接使用 proto。您还需要一个“扩展”功能。

      所以,以 Jeremy 为例,你可以有这样的东西:

      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();
      

      【讨论】:

      • 在该特定示例中,您不需要在 extend 函数中执行 if-check props.hasOwnProperty(prop)
      【解决方案5】:

      如果你不需要构造函数,你可以这样做:

      Object.assign(new CustomType, {});
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-02-08
        • 1970-01-01
        • 1970-01-01
        • 2016-04-15
        • 2019-10-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多