作者: c君不在

  • JavaScript this 值

    JavaScript 中 this 的指向根据上下文及使用方式而有所不同。

    全局上下文 Global Context

    在全局上下文(不在函数体内)中总指向全局对象,如在浏览器中是 window,在 Node.js 则是 global

    函数上下文 Function Context

    • 简单调用
      • 严格模式:undefined
      • 非严格模式:全局对象
      • 可用 callapply 来改变 this
    • 作为对象的方法:指向直接所在的对象,如 a.b.c()cthis 指向 b,适用于普通的对象、原型链方法和 getter/setter
    • 作为构造函数,指向正在构建的对象
    • 作为 DOM 事件处理函数,指向触发事件的元素(指的是外层函数,如果是多层,遵循其余规则)
    • bind:用 f.bind(object) 来返回新的绑定 this 的函数,不论怎么调用,如通过对象方法调用、callapply 都不会改变 this。再次 bind 也不会改变。
    • 箭头函数(arrow function):this 指向词法上下文(实际运行生成箭头函数时上下文)的 this,不会被调用方式改变,但会因生成方式而不同。
    var obj = {
        bar: function() {
            var x = (() => this);
            return x;
        }
    };
    
    var fn = obj.bar();
    console.log(fn() === obj); // true
    
    var fn2 = obj.bar;
    console.log(fn2()() == window); // true
    

    (更多…)

  • 生存从来不容易

    Instapaer 2016 年被收购时,因为有了足够的资源,所以把「高级版」功能做成了免费功能

    但 2018 年又独立经营后,只能重启「高级版」功能来维持运营及开发。

  • 参考文献与注释的区别与关系

    参考文献是作者撰写论著时所引用的已公开发表的文献书目,集中列表于文末;注释主要包括释义性注释引文注释,一般印刷在该页的脚1或集中列于文末参考文献表之前2。释义性注释是对论著正文中某一特定内容的进一步解释或补充说明;引文注释包括各种不宜引入文后参考文献的引文和个别文后参考文献的节略形式,如:

    • 未公开发表的私人通信
    • 档案资料
    • 内部资料
    • 书稿
    • 古籍(1911 年以前出版、无现代版本的各种版本)
    • 仅有中介文献信息的『转引自』类文献
    • 待发表文献
    • 未公开发表的会议文献
    • 文后参考文献的节略形式

    参考文献

    • [1] 中国学术期刊(光盘版)编辑委员会. 中国学术期刊(光盘版)检索与评价数据规范[S]. CAJ-CD B/T 1-2006, 2006: 10–11.

    1. 通常是释义性注释 ↩︎
    2. 通常是引文注释 ↩︎
  • 《编写可维护的 JavaScript》读书笔记

    《编写可维护的 JavaScript(Maintainable JavaScript)》

    编写可维护的 JavaScript

    添加注释的一般原则是,在需要让代码变得更清晰时添加注释:

    • 难以理解的代码
    • 可能被误认为错误的代码
    • 浏览器特性 hack

    事件处理的实践规则:

    • 规则 1:隔离应用逻辑
    • 规则 2:不要分发事件对象

    规则 1 把应用逻辑和时间处理代码中拆分开来,这样应用逻辑可被不同事件或非事件重用,测试时也能直接触发而不必通过模拟事件来触发。

    规则 2 是指事件处理器中处理 event 对象,然后把需要的数据传给应用逻辑,而不是把 event 对象传送下去,应用逻辑依赖具体的数据而不是事件对象。

    事件处理程序应当在进入应用逻辑之前针对 event 对象执行任何必要的操作,包括组织默认事件和阻止事件冒泡,都应当直接包含在事件处理程序中。

    如果所有的失败(错误)都是悄无声息的,首要的问题是那必将消耗你大量的时间才能发现它,更不要说单独隔离并修复它了。

    我们的目的不是防止错误,而是在错误发生时能更加容易地调试。(阅注:在处理接口数据时,有的时候需要编写防御性代码来让业务继续工作而不是直接跑错误终止逻辑。)

    (更多…)

  • import 与 require 的两个差异

    Javascript 的模块化开发,除了 RequireJS 代表的 AMD 外,目前广泛使用的是 Node.js 代表的 CommonJS 以及 ES6 的 module。

    在 babel / webpack 等工具链下,大多数情况下,CommonJS 的 require 和 ES6 的 import 效果等同,babel 的 preset 是 ES2015 以及 webpack 都是把 import 转为 require(webpack 根据 target 再转为 AMD 或 UMP 等格式)。

    但两个规范实质上并不等同,所以存在着不少的区别,如不能 import(var) 但能 require(var),详细可查看 ES6 模块系统,此处记录一下两个可能比较直接影响代码书写的差异点。

    (更多…)

  • git pull 与 rebase

    最初使用独立的工具 git-up,后来 git 支持了同样的功能,通过配置 git config --global alias.up 'pull --rebase --autostash 即可达到同样的效果。

    如果希望在 pull 的时候直接使用 rebase 机制,可以像下面这样配置

    git config --global pull.rebase true
    git config --global rebase.autoStash true
    

    git pull 效果

    git pull 效果

    git pull —rebase 效果

    git pull --rebase 效果

  • 《数据之美》读书笔记

    《数据之美:一本书学会可视化设计(Data Points: Visualization That Means Something)》

    数据之美:一本书学会可视化设计

    笔记摘要

    引言 可视化是一种媒介

    由于数据代表了一定的人物、地点和事物,所以除了真实的数字之外,还有重要的背景信息。数据是关于谁的?它从哪里来以及是什么时候收集的?虽然是计算机生成并输出数据,但我们也需要对这些由人处理的部分负责。

    花一些时间去了解数据以及它们所代表的东西,能加倍提升可视化的效果。

    无论哪一种可视化类型都有其规则可循。这些规则并不取决于设计或统计数字,而受人类感知的支配。它们确保读者能准确解读编码数据。

    规则是应该时时遵循的,而建议则要具体分析,视情况而决定是否采纳。

    (更多…)

  • 明天与意外

    谁知道明天和意外,哪一个先来。

    2018-07-05 泰国普吉岛游船事故

  • Java module

    模块的主要作用有:

    • 模块间需要显示地声明(模块)依赖,而不是以前的简单的基于 classpath
    • 更强的封装隔离,模块不主动导出的话无法被 import;不 open 则无法对其使用反射技术

    指令

    模块通过在模块根目录下的 module-info.java 中的指令来约束使用。

    定义模块

    最好(或则是必须,没找到规定说明) moduleName 和文件夹名称一致,否则 javac 编译时提示 module 和预期的不一致

    module moduleA {
    }
    

    引入依赖

    requires moduleB;
    

    可加 transitive 来表示依赖传递,如 requires transitive moduleB;,然后在 moduleCrequires moduleA; 后,那么在 moduleC 中可使用在 moduleB 中导出的类或接口。

    导出 package

    exports packageFullName;
    

    表示当别的模块(A) requires 了当前模块,那么 packageFullName 这个包(及子孙包)里的 publicprotected 的类和接口可在模块 A 里被访问使用。

    可用 exports packageFullName to moduleA, moduleB 来表示仅 moduleAmoduleB 可访问 packageFullName

    提供服务

    provides full.name.Service with full.name.concreateService, full.name.concreateService2;
    

    表示该模块向外提供 full.name.Service 的实现 full.name.concreateServicefull.name.concreateService2

    使用服务

    uses full.name.Service;
    

    表示该模块需要使用 full.name.Service。同时,不直接依赖具体的实现,而是使用抽象类或接口。然后搭配 ServiceLoader 或别的 IoC 工具来做依赖注入,从而达到和具体实现解耦的目的。

    配合反射

    opens fullPackageName;
    

    表示 fullPackageName 可被使用反射技术。也可使用 opens fullPackageName to moduleA, moduleB 限定开放反射的范围。

    open module moduleD {} 表示整个模块都是开放的。

    其它

    java --list-modules 查看 JDK 内置的模块

    编译运行

    可通过 javac -d mods --module-source-path src $(find src -name "*.java") 来编译运行(多个模块),src 表示各模块所在的目录。

    也可使用 javac -d dist --module-source-path src -m client 来编译指定的模块。

    (更多…)