Javascript声明变量 - 最佳实践

Bri*_*ity 7 javascript performance google-chrome

在阅读http://www.html5rocks.com/en/tutorials/speed/v8/时,有必要在运行时更改变量类型会强制浏览器比保持一致性更加努力.

这是否意味着这不是一个好主意:

 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'
Run Code Online (Sandbox Code Playgroud)

因为这里的类型从null开始,然后变为object,int,boolean arrary.

并且为了简单起见,之后这些类型永远不会改变.

或者这更有效:

 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'
Run Code Online (Sandbox Code Playgroud)

我可以理解从数字到数组的更改类型不是一个好主意.如何在执行期间从null更改为类型?

我读过的书籍和博客主要是说,当值只在运行时知道时,用null(而不是undefined)来定义变量.从表面看,这似乎是错误的,因为使用空类型定义可以避免类型更改.

kmi*_*las 6

这个问题引起了我的兴趣,我设置了一个小提琴来看一些不同用例的表现.

打开控制台查看这个小提琴中的数据
http://jsfiddle.net/kmiklas/MFNak/14/

  • 没有初始化,初始化为null和初始化为数字之间似乎没有什么区别.
  • 除数字外,通过将变量初始化为预期类型(原始帖子中的第二个示例)存在性能损失.
  • 从这些数据可以看出,初始化为零是最佳选择.

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 
~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
Run Code Online (Sandbox Code Playgroud)

代码相当冗长,但根据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('~~~~~~~~~~~~~~~~~~~~~~~~~~~');
Run Code Online (Sandbox Code Playgroud)