月度归档:2018年08月

Mac 下 vim 无法复制到系统剪切板的问题

Mac 下,如果在 VISUAL 模式下选择了内容,然后 "+y 没法复制到系统剪切板,先用 vim --version | grep clip 来查看 vim 的 clip 功能支持情况。如果没开启 clipboard 模块,那么考虑用 MacVim 来替代。

编译安装 MacVim,替换掉系统自带的

brew install macvim --with-override-system-vim

如果编译报类似下面的错,尝试启动 XCode 看看是否有提示需要安装必要工具或同意协议等,参考此 issue

** BUILD FAILED **


The following build commands failed:
    StripNIB English.lproj/Preferences.nib
(1 failure)
make[1]: *** [macvim] Error 65
make: *** [first] Error 2

或者直接安装 MacVim 后 alias

alias vim="/Applications/MacVim.app/Contents/MacOS/Vim"

参考

Vim 编辑 fish 文件启动慢

使用 fish shell,尽管不需要经常编写 fish 脚本,但偶尔可能更新下 fish 配置。但在使用集成了 vim-fish 插件的 Vim 时,打开 fish 文件非常慢,以前一直也没细究,今天找了下解决方案。解决后,虽然还是会比打开别的文件慢,但已在接受范围内。

解决方案:在 vim 配置文件中尽可能地前面添加

if &shell =~# 'fish$'
    set shell=sh
endif

参考

排查 Mac 不能自动睡眠的问题

最近发现工作的 MBP 不能在一段时间后自动睡眠了,根据官方资料以及其它资料确认了开启了自动睡眠的电源设置,关闭了共享、关闭了蓝牙后还是没生效。

后来看到了 pmset(power management) 这个命令,在 pmset -g 命令结果中看到了一个软件名字,在其对应的设置中翻看了一下,关掉其中一个选项后就能正常自动睡眠了。
继续阅读

JS 模块多次 require

Node.JS 中,同一个模块多次 require 得到的是同一个对象,这意味着修改了一个模块的内部值是可以在别的引用了该模块的地方生效的。

Webpack 的打包机制也是基于引用同一个对象来实现的,故同理。

示例代码

mod.js

module.exports = test;

function test() {
   return test.data; 
}

test.add = function(data) {
    this.data.push(data);
};

test.data = [];

comA.js

const mod = require('./mod');

mod.add(1);
mod.add(2);
mod.add(3);

console.log('in comA');

index.js

const mod = require('./mod');
require('./comA');

console.log(mod());   // ==> [1, 2, 3]

性别歧视发散

关于性别歧视(大多是女性处于劣势),不仅仅是男性的原因,长久的社会因素下,女性也会不自主地把自己“低人一等”。

比如,日常生活中还是可以看到女性择偶时会考虑选择比自己收入高的男性来作为婚姻伴侣。

当然,女性没必要为了婚姻而降低自己的生活品质,但要求对方比自己收入高而不是不在意对方收入,这应该是性别歧视的潜意识表现。

Arrow function 与 bind

JavaScript 中 this 的指向有一些规则,其中可通过 bindarrow function 来绑定 this 的指向。

arrow function 在 ES6 中引入,由于可以绑定 this 的原因,常用来替换普通的匿名函数(function() {})。

这两种方式在基于 React 技术中较为广泛地使用,主要是用于事件绑定中。虽然同可绑定 this,但配合类使用时实际是有差别的。简单来说,基于 arrow function 声明的类属性将无法被继承调用。

class A {
    constructor() {
        this.bindMethod = this.bindMethod.bind(this);
    }

    m(p) {
        console.log('m', p);
    }

    bindMethod(p) {
        console.log('bindMethod', p);
    }

    arr = p => {
        console.log('arrow', p);
    };
}

class B extends A {
    m(p) {
        console.log('B');
        super.m(p);
    }

    bindMethod(p) {
        console.log('B');
        super.bindMethod(p);
    }

    arr = p => {
        console.log('B');
        super.arr(p); // Error run with compiled code with es2015+stage0
    };
}

const a = new A();
a.m(1);
a.bindMethod(2);
a.arr(3);

const b = new B();
b.m(1);
b.bindMethod(2);
b.arr(3);

babel 结果(ES2017 + Stage 0)

上面的 class A babel 后(把目标设为 ES2017 是为了简化掉实现 class 继承机制的代码),其中,arrow 形式的 class 属性变成了实例属性,而非原型属性,这样就子类将无法通过 super 来调用。

而通过 bind 方式来实现的 this 绑定则依然保留有原型方法。

class A {
    constructor() {
        this.arr = p => {
            console.log("arrow", p);
        };

        this.bindMethod = this.bindMethod.bind(this);
    }

    m(p) {
        console.log("m", p);
    }

    bindMethod(p) {
        console.log("bindMethod", p);
    }
}

参考

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

继续阅读