简体   繁体   English

Javascript声明变量 - 最佳实践

[英]Javascript declaring variables - best practice

In reading this http://www.html5rocks.com/en/tutorials/speed/v8/ it makes sense that changing the type of variable at runtime forces browsers to work harder than when keeping them consistent. 在阅读这篇http://www.html5rocks.com/en/tutorials/speed/v8/时,有必要在运行时更改变量的类型会迫使浏览器更加努力地工作,而不是保持它们的一致性。

So does that mean this is not a good idea: 这是否意味着这不是一个好主意:

 var x = {
   alpha:    null,
   bravo:    null,
   charlie:  null,
   delta:    null,
   echo:     null
 }

 x.alpha   = {a:1, b:true}
 x.bravo   = 13
 x.charlie = true
 x.delta   = [1,2,3]
 x.echo    = 'abc'

Because here the types started as null, then got changed to object, int, boolean arrary. 因为这里的类型从null开始,然后变为object,int,boolean arrary。

And for the sake of simplicity, afterwards these types never change. 并且为了简单起见,之后这些类型永远不会改变。

Or is this more efficient: 或者这更有效:

 var x = {
   alpha:    {},
   bravo:    0,
   charlie:  false,
   delta:    [],
   echo:     ''
 }

 x.alpha   = {a:1, b:true}
 x.bravo   = 13
 x.charlie = true
 x.delta   = [1,2,3]
 x.echo    = 'abc'

I can understand changing types from say a number to an array is not a good idea. 我可以理解从数字到数组的更改类型不是一个好主意。 What about changing from null into a type once during execution? 如何在执行期间从null更改为类型?

The books and blogs I have read mostly say to define variables with null (as opposed to undefined) when the values are only known at runtime. 我读过的书籍和博客主要是说,当值只在运行时知道时,用null定义变量(而不是undefined)。 At face value, this seems wrong, as defining with their empty type avoids a type change. 从表面看,这似乎是错误的,因为使用空类型定义可以避免类型更改。

Intrigued by this question, I set up a fiddle to look at the performance of some different use cases. 对这个问题感兴趣,我设置了一个小提琴,看看一些不同用例的表现。

Open console to view data in this fiddle 打开控制台以查看此小提琴中的数据
http://jsfiddle.net/kmiklas/MFNak/14/ http://jsfiddle.net/kmiklas/MFNak/14/

  • There seems to be little difference between no initialization, initializing to null, and initializing to a number. 没有初始化,初始化为null和初始化为数字之间似乎没有什么区别。
  • With the exception of numbers, there is a perf loss by initializing variables to the intended type (second example in original post). 除数字外,通过将变量初始化为预期类型(原始帖子中的第二个示例)存在性能损失。
  • From these data, it stands to reason that initializing to nothing is the best option. 从这些数据可以看出,初始化为零是最佳选择。

Typical results from Chrome v32 with n = 100000000: Chrome v32的典型结果,n = 100000000:

number no init: 97.070ms 
number init to null: 98.023ms 
number init to number: 97.246ms 
array no init: 457.494ms 
array init to null: 458.301ms
array init to number: 455.166ms 
array init to array: 836.710ms 
object no init: 508.268ms 
object init to null: 512.312ms 
object init to object: 754.562ms 
number to object: 455.733ms 
array to object: 834.169ms 
object to array: 751.498ms 
~~~~~~~~~~~~~~~~~~~~~~~~~~~ 

Code is rather lengthy, but included below, per SO requirements. 代码相当冗长,但根据SO要求包含在下面。

n = 100000000;
console.time("number no init");
    for (var i = n; i >= 0; i--) { var x; x = 42; };
console.timeEnd("number no init");

console.time("number init to null");
    for (var i = n; i >= 0; i--) { var x = null; x = 42; };
console.timeEnd("number init to null");

console.time("number init to number");
    for (var i = n; i >= 0; i--) { var x = 1; x = 42; };
console.timeEnd("number init to number");

console.time("array no init");
    for (var i = n; i >= 0; i--) { var a; a = [42]; };
console.timeEnd("array no init");

console.time("array init to null");
    for (var i = n; i >= 0; i--) { var a = null; a = [42]; };
console.timeEnd("array init to null");

console.time("array init to number");
    for (var i = n; i >= 0; i--) { var a = 1; a = [42]; };
console.timeEnd("array init to number");

console.time("array init to array");
    for (var i = n; i >= 0; i--) { var a = []; a = [42]; };
console.timeEnd("array init to array");

console.time("object no init");
    for (var i = n; i >= 0; i--) { var a; a = {n:42}; };
console.timeEnd("object no init");

console.time("object init to null");
    for (var i = n; i >= 0; i--) { var a = null; a = {n:42}; };
console.timeEnd("object init to null");

console.time("object init to object");
for (var i = n; i >= 0; i--) { var a = {}; a = {n:42}; };
console.timeEnd("object init to object");

console.time("number to object");
    for (var i = n; i >= 0; i--) { var a = 1; a = {n:42}; };
console.timeEnd("number to object");

console.time("array to object");
    for (var i = n; i >= 0; i--) { var a = []; a = {n:42}; };
console.timeEnd("array to object");

console.time("object to array");
for (var i = n; i >= 0; i--) { var a = {}; a = [42]; };
console.timeEnd("object to array");
console.log('~~~~~~~~~~~~~~~~~~~~~~~~~~~');

Edit: 编辑:

Keep in mind that I only tested in Chrome 32. To accurately draw this conclusion, it would be best to load this fiddle and see results in the more popular desktop and mobile browsers; 请记住,我只在Chrome 32中测试过。要准确得出这个结论,最好加载这个小提琴并在更受欢迎的桌面和移动浏览器中查看结果; particularly, IE and Safari Mobile. 特别是IE和Safari Mobile。

At initialization, all javascript variables are hoisted to the top of the scope with the value of undefined . 在初始化时,所有javascript变量都被提升到范围的顶部,其值为undefined It's not until a variable's value is assigned that a specific type can be assigned. 直到为变量赋值,才能分配特定类型。

So what you're doing here is effectively reassigning the value and type of your variable twice. 所以你在这里做的是有效地重新分配变量的值和类型两次。 The performance cost is likely negligible, however the preferred practice to declare an object whose values are not known is with an object literal: 性能成本可能可以忽略不计,但声明其值未知的对象的首选做法是使用对象文字:

var x = {};

If you try to access a property of an object that doesn't exist, you'll get undefined (which is just as easy to test for as null ). 如果您尝试访问不存在的对象的属性,您将得到未定义(这与测试为null一样容易)。 However, if as you say the properties are known before runtime then there's no reason not to assign those properties straight away, so... 但是,如果您说运行之前已知属性则没有理由不立即分配这些属性,因此......

 x.alpha = {a:1, b:true}
 x.bravo = 13
 x.charlie = true
 x.delta   = [1,2,3]

becomes... 成为...

var x = {
  alpha:    {a:1, b:true},
  bravo:    13,
  charlie:  true,
  delta:    [1,2,3]
};

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

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