Javascript:关于如何定义新数据类型的一些指导原则是什么?

pgp*_*lla 9 javascript types

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

你能举一些例子说明你会在什么时候使用:

  • 一个功能和新:

    // 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();
    
    Run Code Online (Sandbox Code Playgroud)
  • 对象文字&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);
    
    Run Code Online (Sandbox Code Playgroud)
  • 构建对象的函数:

    function customDataTypeFactory(options){
      return {
               a: 'whatever',
               doX: function(){/*some code*/}
             }
    };
    
    // create a new instance of our custom data type
    var obj= customDataTypeFactory(options);
    
    Run Code Online (Sandbox Code Playgroud)

我觉得这可能被标记为重复:newvs Object.create但我的主要兴趣不是讨论哪一个更好,而是知道是否有特定的用例,其中一个应优先于其他用例.

我已经阅读了很多关于相关问题的帖子和来自Crockford的书:Javascript:好的部分.到目前为止,我已经得出结论,这是一个偏好的问题,很难克罗克福德的建议对我产生共鸣:"尽量避免危险和不必要的特征"......我在谈论new.

Ada*_*ark 8

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

function CustomDataType(a)
{
  this.a = a;
  this.b = 2;
}
CustomDataType.prototype = {
  doX : function () {}
};
var obj = new CustomDataType(1);
Run Code Online (Sandbox Code Playgroud)

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

我从未使用过Object.create,除非你陷入一些疯狂的动态hackery,否则我没有任何理由去做.

每当感觉不必为对象创建单独的类时,我就会使用对象文字,例如,如果它是方法的参数(因此调用者不必显式实例化某些东西),或者它是一些不应被访问的内部值由其他人.

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

我不明白为什么new会有危险或不必要的,他在什么情况下这么说?

但我认为很多都归结为品味.保持一致,不要让事情复杂化.

  • Crockford对`new`的问题是:"*如果在调用构造函数时忘记包含`new`前缀,那么`this`将不会绑定到新对象.遗憾的是,这将绑定到全局对象,因此,不是增加你的新对象,而是破坏全局变量.<snip>一个更好的选择是根本不使用`new`.*" (2认同)