Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Javascript中设置函数的最佳方法(可能是通过闭包?)_Javascript_Json_Performance_Closures_Memory Efficient - Fatal编程技术网

在Javascript中设置函数的最佳方法(可能是通过闭包?)

在Javascript中设置函数的最佳方法(可能是通过闭包?),javascript,json,performance,closures,memory-efficient,Javascript,Json,Performance,Closures,Memory Efficient,我有一个web应用程序,它调用一个web服务,返回一些表示对象数组的JSON。每个对象都有一些字段。下面是一些JSON示例: { "data": [ { "id": "12345", "from": { "name": "John Doe", "id": "6789" }, "start_time": "2012-12-16T02:17:20+0000",

我有一个web应用程序,它调用一个web服务,返回一些表示对象数组的JSON。每个对象都有一些字段。下面是一些JSON示例:

{
   "data": [
      {
         "id": "12345",
         "from": {
            "name": "John Doe",
            "id": "6789"
         },
         "start_time": "2012-12-16T02:17:20+0000",
         "end_time": "2012-12-16T02:17:20+0000",
         "publish_time": "2012-12-16T02:17:20+0000"
         }
      },
      {
         "id": "8888",
         "from": {
            "name": "Jane Smith",
            "id": "011"
         },
         "start_time": "2012-12-16T02:17:20+0000",
         "end_time": "2012-12-17T02:17:20+0000",
         "publish_time": "2012-12-16T02:17:20+0000"
         }
      }
   ]
  }
返回后,我使用jQuery的parseJSON()方法将其膨胀为一个对象数组(保留“data”值)。这一切都很好,但在我有了阵列之后,我有了几个可以在每个阵列插槽上操作的函数。例如,假设有一个名为GetDuration()的函数,它将打印结束时间和开始时间之间的时间间隔。在任何情况下,我定义了几个函数(可能是15个),在这一点上,我只是在整个数组中迭代,并使用函数的副本膨胀每个对象。范例

for (var i=0;i<data.length;i++)
 data[i].TimeLapse = function() { ... };

for(var i=0;i我想你说的是,你想用JSON来设置不同类型对象的属性,每个对象都有自己的方法?不清楚你在追求什么,或者目前正在做什么。但是如果我是对的,你肯定做错了

简言之,不要向数据中添加函数。相反,请使用可在创建时接受数据的方法创建类

// Constructor, accepts an object expected to have data about a user
var User = function(data) {

  // save a field from the passed in user data on this instance
  this.name = data.name;
};

// a method every User object will have that uses some bit of user data
User.prototype.sayHi = function() {
  alert('Hi, my name is ' + this.name);
};

// A place to put our new user objects
var users = [];

// An array of objects to iterate through
var jsonData = [
  {name: 'Joe'},
  {name: 'Sally'}
];

// Iterate through the array
for (var i = 0; i < jsonData.length; i++) {

  // make a user, passing the constructor the data object for that user
  users.push( new User(jsonData[i]) );
}

users[0].sayHi(); // alerts: "Hi, my name is Joe"
users[1].sayHi(); // alerts: "Hi, my name is Sally"
//构造函数,接受预期包含用户数据的对象
var User=函数(数据){
//保存此实例上传入的用户数据中的字段
this.name=data.name;
};
//每个用户对象将拥有的一种方法,它使用一些用户数据
User.prototype.sayHi=函数(){
警报(‘嗨,我的名字是’+这个名字);
};
//放置新用户对象的位置
var用户=[];
//要迭代的对象数组
var jsonData=[
{姓名:'乔'},
{姓名:'Sally'}
];
//遍历数组
对于(var i=0;i
正如其他人在评论中所写,不清楚您想要什么,但这听起来与您所描述的最接近:

function make_duration_fun(x) {
    return function() { return GetDuration(x.start_time, x.end_time); };
}
然后,您的循环可以执行以下操作:

data[i].TimeLapse = make_duration_fun(data[i]);
只有一个duration函数,但每次调用
make_duration\u fun
时,都会得到一个新的闭包,该闭包使用相同的函数和不同的
x
绑定

  • 如果必须循环每个数据元素,为什么不计算每个项目的持续时间并将其作为属性添加

  • 如果您愿意将每个数据对象的所有属性复制到一个新的数据对象,您可以在该对象的构造函数上使用原型,并向原型中添加诸如
    timeLapse
    之类的函数。然后,所有数据对象都通过原型继承连接起来工作。但这是一项额外的工作,可能无法执行曼特

  • 您可以使用JSONP或执行返回代码的变体,而不是直接使用JSON

    {
       "data": [
          new DataItem(
             12345",
             {
                "name": "John Doe",
                "id": "6789"
             },
             "2012-12-16T02:17:20+0000",
             "2012-12-16T02:17:20+0000",
             "2012-12-16T02:17:20+0000"
          ),
          // ... and so on ...
       ]
    }
    
    与直接向上对象表示法(禁止执行代码,只允许有值)相反,您必须小心执行代码,但我相信这样做是安全的。例如,您可以不说
    newdataitem()
    只需为每个最终对象嵌入一个数组,然后在其上循环并使用,
    apply
    ing和
    new
    关键字将数组转换为对象,并将项目数组传递到
    DataItem
    ,以获得新的原型有线对象

  • 数据
    数组中的每个项目中添加函数,理论上可能会占用比所需更多的内存。根据您要权衡的时间和空间,还有其他选项。例如:

    function ItemWrapper(dataobj) {
        for (key in dataobj) {
           if (!dataobj.hasOwnProperty(key)) { continue; }
           this[key] = dataobj[ky];
        }
        this.timeLapse = (new Date(this.end_time)).getTime() - (new Date(this.start_time)).getTime(); // assign simple static properties
    }
    
    ItemWrapper.prototype.dynamicFn = function () {
       return this.x - this.y; // changeable properties accessed as functions
    }
    
    var currentObj = new ItemWrapper(data[23]);
    console.log(currentObj.timeLapse); // static
    console.log(currentObj.dynamicFn()); //dynamic
    
    问题是:您希望在使用时还是在解析时执行此包装?在解析时执行此操作实际上是我的建议#2。但此建议仅在您需要特定项目时执行。我不知道您的项目访问模式,因此这可能不理想,但至少是一个选项

  • 使用
    应用
    调用

    function timeLapse() {
       return (new Date(this.end_time)).getTime() - (new Date(this.start_time)).getTime();
    }
    
    var Item16Elapsed = timeLapse.apply(data[16]);
    
    通过这种方式,您不会到处附加函数,也不会将对象转换为新的原型有线对象,但您必须以稍微不同的方式调用对象


  • 你能给出一个更完整的例子来说明你是如何使用这些函数的吗?它们是如何传递数据的,它们返回什么?如果我们看不到你目前是如何做的,很难给出建议。JSON越少,代码就越多。正如@AlexWayne所说,我们真的不能给出任何建议,这取决于你试图做什么和完成什么。然而,如果您已经设置好了函数,我只是将其设置为常规函数,然后执行类似于
    data[I].TimeLapse=GetDuration(data[I].start\u time,data[I].end\u time)的操作;
    闭包仅在“保留对定义它们的环境的绑定”的情况下才有帮助.我不知道这会有什么帮助。正如亚历克斯·韦恩(Alex Wayne)所说,一个完整的(最低限度的)示例会有很大帮助。感谢大家提供的有用答案,如果我的问题缺乏细节,我很抱歉。我已经开始进行更改。根据Erik的评论,我注意到一些可以简单地用属性替换的函数。进行此更改,我希望能获得内存和效率的提升(无需跳转堆栈)。在这方面有一个折衷:如果数据发生更改,则属性将反映过期的值。但是,对于某些属性来说,这不是问题,因此这是一个值得折衷的折衷。对于其他一些情况,保留函数是有意义的,因为数据可以更改,并且…我希望反映最新的数据。为了提供更多详细信息,函数(和属性)是通过KnockoutJS绑定到的。因此有属性、函数和一些KO.Computed函数。有趣的是,KO.Computed有一个称为“deferEvaluation”的功能(这是自解释的)。当应用该功能时,可能还有一些额外的内存