Math.pow(1.1, Day)

JavaScript中的falsy value

JavaScript中的falsy value

在彻底弄清nullundefined的区别时。延伸学习了JavaScript中的falsy value

###Falsy Value

什么时falsy value呢?《JS Definitive Guide》和《JS The Good Parts》中都提到了falsy value的概念。falsy value指的是逻辑表达式的结果为假的情况。以下值会被当作falsy value:

  • false
  • null
  • undefined
  • ’’
  • 0
  • NaN

所有这些值的if ( !x ) { }都会通过。除此以外其他的值都是true value真值,if ( x ) { }都会通过。

但有种情况需要注意:

对于一个window对象的属性(全局变量),比如window.bar。如果bar未定义在window中,那么使用if (bar ) { }会报错。这时候需要使用if ( typeof bar === 'undefined' )或者if ( 'bar' in window )

###具体的falsy value

首先要更正原问题提出者的一个错误:null不是一个对象。 尽管使用typeof null会返回object,但这是typeof的bug。null是一个primitive value,它没有其他属性和方法,你也无法给它添加属性和方法。它不是一个对象。

接下来对上述各个falsy value,借用排名第一的答案来做说明。

背景:

我需要引用一个叫name的变量的值,因此我问JavaScript解释器:告诉我name的值是多少。

场景一: (name 为 undefined)

  • name? 什么是name? 我不知道你在说什么,之前也从没人提过它。

场景二: (name = null)

  • 我知道有name这个变量存在,但我不知道它的值是多少。

场景三: (name = false)

  • name的值为布尔值false

场景四: (name = ‘‘)

  • name的值是一个空字符串

场景五: (name = NaN)

  • name的值是一个无穷大的数字

###垃圾回收

falsy valuenull,你也许会想到或者曾经听到过,它跟垃圾回收相关。我们就来看看JavaScript的垃圾回收。

跟其他很多种高级语言一样,JavaScript的垃圾回收机制也是采用的引用计数技术。

引用计数是用图的结构来表示当前每块内存的引用情况,当图中出现无法到达的_(unreachable )_节点的时候,这块节点的内存就是可以被回收的对象。示例:

reference-counting-GC

而对于引用计数中的具体的无法到达的判定问题,使用的是Mark-and-sweep算法

大致过程如下:(摘自MSDN - Mark and Sweep Garbage Collection

void GC()
{
    HaltAllProcessing();    // 阻塞正常程序的执行
    ObjectCollection roots = GetRoots();
    for(int i = 0; i < roots.Count(); ++i)
        Mark(roots[i]); //标记
    Sweep();    //回收
}

JavaScript引擎会定期扫一遍这个图,标记无法到达的节点,然后回收这些节点的内存。GC过程会阻塞正常程序的执行。

####falsy value与垃圾回收

null && undefined与垃圾回收有点关系:它销毁目标变量对当前内存的引用。

比如:var a = new Obj(); var b = a; a = null;,之后,a变量就不再指向obj那块内存的引用了。但b仍然指向obj那块内存。

因此,a = null能促进垃圾回收,但不会直接引发垃圾回收。

另外,delete运算符能删除一个对象的某个属性,删除的结果就是obj.attr = undefined。因此,它也能促进垃圾回收。(但之前在如何移除一个对象的某个属性中已经提到过,delete效率低,少用)