简体   繁体   English

在JavaScript / Nodejs中动态处理未定义变量的最佳实践

[英]Best practice to handle undefined variables dynamicaly in JavaScript/Nodejs

Ok, maybe is not the best title, but I lacked inspiration, so here goes: 好的,也许不是最好的标题,但是我缺乏灵感,所以去了:

Let's say you have a "global" (not really) variable to store temporary data and sub data as random users interact with your server. 假设您有一个“全局”(不是真的)变量,用于在随机用户与服务器交互时存储临时数据和子数据。 Normally on the first interaction with your server, the main variable will be undefined so you need to handle that case. 通常,在与服务器的第一次交互中,main变量是不确定的,因此您需要处理这种情况。

Now, what puzzled me about this, is what's the best practice performance wise to do this if there are a lot of users and a lot way more interactions with the variable. 现在,困扰了我这一点,是什么是最好的做法性能明智的,如果有大量的用户和大量的与可变的方式更多的互动做到这一点。

Puzzled? 困惑? Yeah, I know, words are not my strong point so let me show you in code 是的,我知道,文字不是我的强项,所以让我向您展示代码

So you have 所以你有了

var user_data = [];

Then a function that handles user interaction to store data 然后是一个处理用户交互以存储数据的功能

function writeData(uid, data_name, data)

Now, on first interaction, user_data[uid][data_name] is undefined, and so it's user_data[uid] 现在,在第一次交互时,user_data [uid] [data_name]是未定义的,因此它是user_data [uid]

I know you can handle this 2 ways: 我知道您可以通过以下两种方式处理:

With if - 如果 -

if(!user_data[uid]) user_data[uid] = {}
 user_data[uid][data_name] = data

With try/catch 使用try / catch

try{user_data[uid][data_name] = data} 
catch(e) {user_data[uid] = {}; writeData(uid, data_name, data)}

The if will check on every interaction, and like I said there are a lot. if是否会检查每个交互,就像我说的那样,有很多。 Try catch will trigger once, but it has a cost as a block (afaik) 尝试捕获将触发一次,但会带来成本损失(afaik)

Which one is better? 哪一个更好? Or is there a another better way 还是有另一种更好的方法

@Nertan , There is a partiality in your proof :P . @Nertan,您的证明中有一部分是:P。 I have slightly tweeked the ternary way (same as the order of execution in if way). 我对三元方式做了些微调整(与if方式中的执行顺序相同)。 With this you can conclude. 这样就可以得出结论。

 //var present = require('present'); function test(val,ud,fun) { var k = 10000000; var t = Date.now(); for(var i=0; i<k;i++) { var uid = Math.ceil(Math.random()*1000); fun(uid,ud,"value"); } var tf = Date.now()-t; return tf; } function setValue_Opp(uid,ud,value) { (!ud[uid] && (ud[uid] = {})) && (ud[uid].value = value); } function setValue_Try(uid,ud,value) { try{ ud[uid].value = value} catch(e){ ud[uid] = {}; setValue_Try(uid,ud,value)}; } function setValue_Cond(uid,ud,value) { if(!ud[uid]) ud[uid] = {} ud[uid].value = value; } var k1=0; var k2=0; var k3=0; for(var i=0;i<10;i++){ k1+=test(1,{}, setValue_Cond); k2+=test(2,{}, setValue_Try); k3+=test(3,{}, setValue_Opp); } console.log(k1,k2,k3) 

I feel we can take advantage of ES6 ternaries as below: 我觉得我们可以利用以下ES6三元组:

 let user_data = {} const writeData = (uid, data_name, data) => { ((user_data[uid] || (user_data[uid] = {})) && (user_data[uid][data_name] = data )) console.log(user_data) // perform write action } writeData('1',"test","test1"); writeData('2',"test","test2"); writeData('1',"test","test3"); 

Ok, so I had to rewrite the test because it doesn't work fine in the Snippet 好的,所以我不得不重写测试,因为它在代码段中无法正常工作

So I made this for node.js: 所以我为node.js做的是:

 var present = require('present'); function test(val,ud,fun) { var k = 10000000; var t = present(); for(var i=0; i<k;i++) { var uid = Math.ceil(Math.random()*1000); fun(uid,ud,"value"); } var tf = present()-t; console.log("END "+val+" at "+tf); return tf; } function setValue_Opp(uid,ud,value) { (ud[uid] || (ud[uid] = {})) && (ud[uid].value = value); } function setValue_Try(uid,ud,value) { try{ ud[uid].value = value} catch(e){ ud[uid] = {}; setValue_Try(uid,ud,value)}; } function setValue_Cond(uid,ud,value) { if(!ud[uid]) ud[uid] = {} ud[uid].value = value; } var k1=0; var k2=0; var k3=0; for(var i=0;i<10;i++){ k1+=test(1,{}, setValue_Cond); k2+=test(2,{}, setValue_Try); k3+=test(3,{}, setValue_Opp); } console.log(k1,k2,k3) 

And in the end: 3244.328997004777 3695.0267750024796 3437.6855720058084 最后:3244.328997004777 3695.0267750024796 3437.6855720058084

Which means: 意思是:

The best is the classical if 最好的是经典的

The second best is condintional operators method 次优是常规运算符方法

And the worst is the try-catch 最糟糕的是尝试捕获

So it seems the classics win 看来经典赢得了

Edited: 编辑:

With further tests thanks to @CRayen the best method is : 通过@CRayen进行进一步的测试,最好的方法是:

  (!ud[uid] && (ud[uid] = {})) && (ud[uid].value = value); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM