Javascript:关于如何定义新的数据类型,有哪些指导原则?

Javascript:关于如何定义新的数据类型,有哪些指导原则?,javascript,types,Javascript,Types,假设您正在创建数据类型并公开其行为 你能举例说明你什么时候会使用: 新功能(&N): // define new data type var CustomDataType= function(){ this.a='whatever'; this.doX= function(){/*some code*/}; } // create a new instance o

假设您正在创建数据类型并公开其行为

你能举例说明你什么时候会使用:

  • 新功能(&N):

    // define new data type
    var CustomDataType= function(){ 
                          this.a='whatever';
                          this.doX= function(){/*some code*/};
                        }
    
    // create a new instance of our custom data type
    var obj= new customDataType();
    
  • 对象文字&object.create:

    // define new data type
    var customDataType = {
                           a: 'whatever',
                           doX: function(){/*some code*/}
                         }
    
    // create a new instance of our custom data type
    var obj= Object.create(customDataType);
    
  • 构建对象的函数:

    function customDataTypeFactory(options){
      return {
               a: 'whatever',
               doX: function(){/*some code*/}
             }
    };
    
    // create a new instance of our custom data type
    var obj= customDataTypeFactory(options);
    
我觉得这可以被贴上重复的标签:
new
vs
Object.create
,但我的主要兴趣不是讨论哪一个更好,而是知道是否有特定的用例,其中一个应该比其他更好


我已经阅读了很多关于相关问题的帖子和Crockford:Javascript:the good parts的书。到目前为止,我已经得出结论,这是一个偏好的问题,Crockford的建议对我产生了很大的共鸣:“尽量避免危险和不必要的功能”。。。我说的是
new

我将从我通常定义类的方式开始:

function CustomDataType(a)
{
  this.a = a;
  this.b = 2;
}
CustomDataType.prototype = {
  doX : function () {}
};
var obj = new CustomDataType(1);
我在构造函数中分配变量是因为
F.prototype={a:[1,2,3];}
有问题,数组将在实例之间共享,除非在构造函数中重新初始化属性(对于所有非基元类型都有问题)。当属性以某种方式依赖于构造函数的参数时,也需要它。我在原型中声明方法,以便在所有实例之间共享它们,如果使用继承,这意味着可以进行超级调用,这也会减少内存使用,因为该方法只需分配一次(尽管这可能不是什么大问题)

我从来没有使用过Object.create,我看不出有任何理由这样做,除非你陷入了疯狂的动态黑客

每当感觉没有必要为对象创建单独的类时,我就使用对象文本,例如,如果它是方法的参数(因此调用方不必显式地实例化某些对象),或者如果它是其他任何人都不应该访问的一些内部值

您的工厂本质上与对象文字相同。我想如果您需要创建一些jsonesque结构并设置一些默认值,它可能会很有用

我不明白为什么新的是危险的或不必要的,在什么情况下他这么说的


但我认为这很大程度上取决于味道。保持一致,不要使事情复杂化。

您的第一个和第三个版本将属性直接放在新对象上。在第二个版本中,对象继承属性。我不知道你的问题有什么具体的答案。如果使用
new
调用,第一个函数将使用构造函数,而
instanceof
将用于标识该对象。第三个不需要使用
new
,但是
instanceof
就没有那么有用了。第二个将再次继承属性,因此以这种方式构建多个对象都将共享数据,并且所有对象都将观察到继承对象的更新……并且不要太在意Crockford的危险警告。我觉得他有点太担心了。我的意思是,把它全收进去,但要小心一点。
this.doX=
应该是
doX:
在最后两段代码中,斯克罗克福德的
问题是:“如果调用构造函数时忘记包含
new
前缀,则
将不会绑定到新对象。不幸的是,这将绑定到全局对象,因此您将不增加新对象,而是对全局变量进行重击。一个更好的选择是根本不使用
new
。“啊,我记得读过这方面的内容,可能是从他那里读到的。你可以做类似
函数C(x){如果(this==window)返回新的C(x);this.x=x;}
我在编写JS时遇到了很多麻烦,但我从未忘记编写
new
。@AdamBergmark抛出一个错误来强制使用new不是更好吗?