欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

js语言精粹读书笔记

程序员文章站 2022-07-14 20:45:21
...
  1. 全书贯穿一个method方法定义新方法:
Function.prototype.method = function(name, func) {
    if (!this.prototype[name]) {
        this.prototype[name] = func;
    }
    return this;
};
  1. js只有一种数字类型,表示为64位浮点数,没有分离出整数类型,1和1.0的值相同
  2. Infinity表示所有大于1.79769313486231570e+308的值
  3. 运算符优先级
    js语言精粹读书笔记
  4. 运算汇总取余向0靠近取整,取模向负无穷靠近取整, 所以js中的模运算符号实际上是取余运算
  5. js对象属性名字可以为空字符串
  6. || 一般用来填充默认值,&&可以防止取值undefined的typeError错误
  7. 原型连接只有在检索的时候才会被用到
  8. 当函数中有return没有返回一个对象,且这个函数被当做构造函数使用,则return返回this
  9. 经典递归
// 定义walk_the_DOM函数,它从某个指定的节点开始,按照html源码中的顺序访问该树的每一个节点
// 它会调用一个函数,并依次传递每个节点给它,walk_the_DOM调用自身去处理每一个子节点

var walk_the_DOM = function walk(node, func) {
    func(node);
    node = node.firstChild;
    while (node) {
        walk(node);
        node = node.nextSibling;
    }
};

// 定义 getElementsByAttribute 函数。它以一个属性名称字符串
// 和一个可选的匹配值作为参数
// 它调用walk_the_DOM,传递一个用来查找节点属性名的函数作为参数。
// 匹配的节点会累加到一个数组中

var getElementsByAttribute = function(att, value) {
    var result  = [];
    walk_the_DOM(document.body, function(node) {
        var actual = node.nodeType === 1 && node.getAttribute(att);
        if (typeof actual === 'string' && (actual === value || typeof value !== 'string')) {
            result.push(node)
        }
    });
    return results;
};

11 一些语言提供了尾递归,如果一个函数返回资深的递归调用结果,调用过程会被替换成一个循环,可以显著提高速度,但是js并么有提供尾递归优化。
12 闭包

// 糟糕的例子
// 构造一个函数,用错误的方式给一个数组中的节点设置事件处理程序。
// 当点击一个节点时候,按照预期,应该弹出一个对话框显示一个节点的序号
// 但是它总会显示节点的个数
var add_the_handlers = function (nodes) {
    var i;
    for (i = 0; i < nodes.length; i++) {
        nodes[i].onclick = function() {
            alert(i);
        };
    }
}

用闭包改良后的例子,与之前的例子相比,这边使用了闭包返回了一个函数,在绑定事件时候执行helper函数保证事件函数变量i的值是函数构造时候的值。
其次,我们应该避免在循环中创建函数,引起无谓的计算,影响性能。

// 改良后的例子
// 构造一个函数,用正确的方式给一个数组中的节点设置事件处理程序
// 点击一个节点,将会弹出一个对话框显示节点的序号
var add_the_handlers = function (nodes) {
    var helper = function (i) {
        return function(e) {
            alert(i);
        };
    };
    var i;
    for (i = 0; i < nodes.length; i++) {
        nodes[i].onclick = helper(i);
    }
}

13 模块的一般形式:利用闭包可以创建可以访问私有变量和内部函数的特权函数,最后返回这个特权函数;
14 柯里化 允许我们把函数与传递给它的参数相结合产生一个新的函数

Function.method('curry', function() {
    var slice = Array.prototype.slice,
    that = this;
    return function () {
        return that.apply(null, args.concat(slice.apply(arguments)))
    };
})

15 函数记忆,理解为缓存

// 斐波那契数列,糟糕的写法
// 我们调用了11次,它自身调用442次计算
var fibonacci = function (n) {
    return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
};
for (var i = 0; i <= 10; i += 1) {
    document.writeln('//' + i + ':' + fibonacci)
}
// 0: 0
// 1 : 1
// 2 : 1
// 3 : 2
// ...
// 10 : 55
// 改良后的写法, 利用闭包存储
var fibonacci = function () {
    var memo = [0, 1];
    var fib = function(n) {
        var result = memo[n];
        if (typeof result !== 'number') {
            result = fib(n - 1) + fib (n - 2);
            memo[n] = result;
        }
        return result;
    };
    return fib;
}();

提取记忆函数

var memoizer = function (memo, formula) {
    var recur = function() {
        var result = memo[n];
        if (typeof result !== 'number') {
            result = formula(recur, n);
            memo[n] = result;
        }
        return result;
    };
    return recur;
};

改良后的fibonacci:

var fibonacci = memoizer([1, 1], function(recur, n) {
    return recur(n - 1) * recur(n - 2)
})

阶乘:

var factorial = memoizer([1, 1], function(recur, n){
    return n * recur(n-1)
});

16 继承

Function.method('inherits', function(Parent) {
    this.prototype = new Parent();
    return this;
})

使用伪类的缺点:
- 没有私有环境,所有属性都是公开的
- 无法访问父类的方法
- 使用构造器函数忘记new函数的时候,this就绑定在了全局变量上,污染全局,没有任何错误提示

17 纯粹的原型模式中,我们会摒弃嘞,转而专注对象。差异化继承:

var myMammal = {
    name: 'herb the name',
    says: function() {
        this.saying || '',
    },
};

var myCat = Object.create(myMammal);
myCat.name = 'Tom';
myCat.saying = 'meow';

17 判断是否为数组的方法:

var is_array = function () {
    return Object.prototype.toString.apply(value) === '[Object Array]'
}

18 如果想把大量的字符串片段组成一个字符串,将这些片段放到一个数组中并用join方法链接起来通常比+运算符链接要快(古老浏览器,现代浏览器已经优化)

未完待续~