跳到主要内容

《你不知道的javascript》笔记

    • undefined
    • null
    • false
    • +0、-0 和 NaN
    • ""
  1. 现在我们终于明白 ~ 有什么用处了! ~ 和 indexOf() 一起可以将结果强制类型转换(实际 上仅仅是转换)为真 / 假值:

    var a = "Hello World";
    ~a.indexOf( "lo" ); // -4 // true
    if (~a.indexOf( "lo" )) { // 找到匹配!

    }
    ~a.indexOf( "ol" );
    !~a.indexOf( "ol" );
    if (!~a.indexOf( "ol" )) { // true 没有找到匹配!

    }
    如果 indexOf(..) 返回 -1~ 将其转换为假值 0,其他情况一律转换为真值。

    稍微说下,实际中用到这个可能会被打。至少我还没有遇到过这种的代码

  2. ~~x 能将值截除为一个 32 位整数,x | 0 也可以,而且看起来还更简洁。

    出于对运算符优先级(详见第 5 章)的考虑,我们可能更倾向于使用 ~~x。

    我们在使用 ~ 和 ~~ 进行此类转换时需要确保其他人也能够看得懂。

  3. 常见的误区是“== 检查值是否相等,=== 检查值和类型是否相等”。

    正确的解释是:“== 允许在相等比较中进行强制类型转换,而 === 不允许。”

  4. var i = 2;
    Number.prototype.valueOf = function() {
    return i++;
    };
    var a = new Number(42);
    if (a == 2 && a == 3) {
    console.log( "Yep, this happened." );
    }

    之前遇到这个面试题,就感觉很神奇,可能就是从这本书里搞到的这种有点算是刁难的面试题吧。

  5. JSON 被普遍认为是 JavaScript 语言的一个真子集,js{"a":42} 这样的 JSON 字符串会被当作合法的 JavaScript 代码(请注意 JSON 属性名必须使用双引号!)。其实不是!如果在控制台中输入 js{"a":42} 会报错。

    因为标签不允许使用双引号,所以 "a" 并不是一个合法的标签,因此后面不能带 :。

    JSON 的确是 JavaScript 语法的一个子集,但是 JSON 本身并不是合法的 JavaScript 语法。

    经过我的测试,在Google和Safra中都不会报错,在Firefox中确实报错,IE的话,对不起我没有这个浏览器

  6. 尤其要提出的是,在某些条件下,某些浏览器的 console.log(..) 并不会把传入的内容立 即输出。出现这种情况的主要原因是,在许多程序(不只是 JavaScript)中,I/O 是非常低 速的阻塞部分。所以,(从页面 /UI 的角度来说)浏览器在后台异步处理控制台 I/O 能够提 高性能,这时用户甚至可能根本意识不到其发生。

    var a = {
    index: 1
    };
    // 然后
    console.log( a ); // ??
    // 再然后 a.index++;

    我们通常认为恰好在执行到 js console.log(..) 语句的时候会看到 a 对象的快照,打印出类 似于js{ index: 1 }这样的内容,然后在下一条语句jsa.index++执行时将其修改,这句的执 行会严格在 a 的输出之后。

    多数情况下,前述代码在开发者工具的控制台中输出的对象表示与期望是一致的。但是, 这段代码运行的时候,浏览器可能会认为需要把控制台 I/O 延迟到后台,在这种情况下, 等到浏览器控制台输出对象内容时,jsa.index++ 可能已经执行,因此会显示 js{ index: 2 }

    到底什么时候控制台 I/O 会延迟,甚至是否能够被观察到,这都是游移不定的。如果在调 试的过程中遇到对象在 jsconsole.log(..) 语句之后被修改,可你却看到了意料之外的结果, 要意识到这可能是这种 I/O 的异步化造成的。

    console是可能被阻塞的,好吧,我之前不知道,不过我也确实不经常用console来调试,我更习惯打断点。

  7. 我们在假装并行执行多个任务时,实际上极有可能是在进行快速的上下文切换,比如与朋 友或家人电话聊天的同时还试图打字。换句话说,我们是在两个或更多任务之间快速连续 地来回切换,同时处理每个任务的微小片段。我们切换得如此之快,以至于对外界来说, 我们就像是在并行地执行所有任务。

    这听起来是不是和异步事件并发机制(比如 JavaScript 中的形式)很相似呢?!如果你还 没意识到的话,就回头把第 1 章再读一遍吧!

    实际上,把广博复杂的神经学简化(即误用)为一种这里我足以讨论的形式就是,我们大 脑的工作方式有点类似于事件循环队列。

    如果把我打出来的每个字母(或单词)看作一个异步事件,那么在这一句中我的大脑就有 几十次机会被其他某个事件打断,比如因为我的感官甚至随机思绪。

    我不会在每次可能被打断的时候都转而投入到其他“进程”中(这值得庆幸,否则我根本 没法写完本书!)。但是,中断的发生经常频繁到让我觉得我的大脑几乎是不停地切换到 不同的上下文(即“进程”)中。很可能 JavaScript 引擎也是这种感觉。

    其实看起来很强大的引擎、编译器、应用等,底层原理往往没有想象中复杂,缓存和事件循环往往是底层的一些原理,其实任何事情都是有代价的,算法就是用代码复杂度来换空间或者事件的复杂度,有些时候我们有需要用时间复杂度去换空间复杂度,或者相反,但是原理总是那些。

  8. 唯一比不知道代码为什么崩溃更可怕的事情是,不知道为什么一开始它是工 作的!这就是经典的“纸牌屋”心理:“它可以工作,可我不知道为什么, 所以谁也别碰它!”你可能听说过“他人即地狱”(萨特)这种说法,对程 序员来说则是“他人的代码即地狱”。而我深信不疑的是:“不理解自己的代 码才是地狱。”回调就是主要元凶之一。

  9. 回调最大的问题是控制反转,它会导致信任链的完全断裂。

    现代的计算机基础都是基于约定和信任建立起来的,我们很多时候不得不信任数据,即使有基本的判断也并不能完全判定通过,所以信任别人,但是要做基本的防错。

Loading Comments...