JavaScript中的falsy values

原文 标签 IT工具网 javascript

原问题:Why is null an object and what’s the difference between null and undefined?

提问者主要是问null,以及nullundefined的区别。延伸一下,可以一起说说JavaScript中的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效率低,少用)

相关文章:

为什么Java的Vector类被认为是过时的或者废弃的

如何克隆Clone一个JavaScript对象

javascript - 复杂的C#对象

javascript - 确定两个点是否在javascript中一行的同一侧

如何学习数据结构与算法

LinkedList、ArrayList各自的使用场景,如何确认应该用哪一个呢?

javascript - JavaScript中的货币转换器出现问题

javascript - api调用后返回未定义的 meteor 方法

javascript - JavaScript排序获取的数据

Java修饰符:public,protected,private,不加修饰符。有什么区别呢?