JavaScript语言精粹

朱雀 2021-04-19 15:04 560阅读 0赞

一、语法

  • 运算符优先级
. [] () 提取属性与调用函数
delete new typeof + - 一元运算符
* / % 乘法、除法、求余
+ - 加法/连结、减
>= <= > < 不等式运算符
=== !== 等式运算符
&& 逻辑与
?: 三元

:在js中,“%”不是通常数学意义上的模运算,而实际上是“求余”运算。两个运算数都为正数时,求模运算和求余运算的值相同;两个运算数存在负数时,求模运算和求余运算的值则不相同。

二、对象

  • js包含一种原型链的特性,允许对象继承另一个对象的属性。正确地使用它能减少初始化时消耗的时间和内存。
  • 如果属性名是一个合法的js标识符且不是保留字,则不强制要求用引号括住属性名。
  • 反射 -— 检查对象有什么属性

只用typeof是不够的,原型链中的任何属性都会返回值,如:

  1. typeof flight.toString //fuuction
  2. typeof flight.constructor //function

有两种方法可以去处理这些不需要的属性:

  1. 让程序检查并丢弃为函数的属性;
  2. 使用hasOwnProperty(不会检查原型链)方法;

    • 减少全局变量的污染。全局变量削弱了程序的灵活性,应该避免使用。

三、函数

所谓编程,就是将一组需求分解成一组函数与数据结构的技能。

每个函数在创建时会附加连个隐藏属性:函数的上下文和实现函数行为的代码; 函数在调用时,除了有声明是的形式参数,每个函数还接收连个附加的参数:thisarguments arguments 不是一个真正的数组,可以使用一下方法来转化为真正数组:

  1. Array.prototype.slice.apply(arguments);
  2. Array.prototype.concat(thisArg, arguments);
  • 函数的4种调用模式:
  1. 方法调用模式;
  2. 函数调用模式;
  3. 构造器调用模式 (new);
  4. apply调用模式;

    • 扩充类型的功能

举例:

  1. function.prototype.method = function(name, func){
  2. this.prototype[name] = func;
  3. return this;
  4. }

通过给function.prototype增加一个method方法,我们下次给对象增加方法的时候就不必键入prototype这几个字符。省去一些麻烦。

  • 函数中声明变量

最后的做法是在函数体的顶部声明函数中可能用到的所有变量。

  • 模块

可以使用函数和闭包来构造模块。模块是一个提供接口却隐藏状态与实现的函数或对象。

模块模式的一般形式 是:一个定义了私有变量和函数的函数; 利用闭包创建可以访问私有变量和函数的特权函数; 最后返回这个特权函数,或者把他们保存到一个可访问的地方。模块模式经常结合单例模式(Singleton Pattern)使用。

  • 级联
  • 柯里化

把函数与传递给它的参数相结合, 产生出一个新的函数。

  • 记忆(加速程序计算的一种优化技术,如用闭包存储结果)

四、继承

在那些基于类的语言中,继承(inheritance或extends)提供了两个有用的服务。

  • 它是代码重用的一种形式。
  • 引入了一套类型系统的规范。
  1. 实现 new 一个对象的内部实现机制

    Function.method(‘new’, function () {

    1. // 创建一个新对象,它继承自构造器函数的原型对象
    2. var that = Object.create(this.prototype);
    3. // 调用构造器函数, 绑定 -this- 到新对象上
    4. var other = this.apply(that, arguments);
    5. // 如果它的返回值不是一个对象, 就返回该新对象
    6. return (typeof other === 'object' && other) || that

    })

  1. 对象说明符

    var myObject = maker(f, l, m, c, c);

==>

  1. var myObject = maker({
  2. first: f,
  3. middle: m,
  4. last: l,
  5. state: s,
  6. city: c
  7. })
  1. 利用原型进行差异化继承

通过定制一个新的对象,我们指明它与所基于的基本对象的区别。

  1. 函数化 —- 应用模块模式

一个函数化构造器的伪代码模块:

  1. var constructor = function (spec, my) {
  2. var that, 其他的私有变量
  3. my = my || {};
  4. 把共享的变量和函数添加到my
  5. that = 一个新对象
  6. 添加给that的特权方法
  7. return that;
  8. }

五、 数组

  • JS允许数组包含任意混合类型的值
  • JS数组的length是没有上界的, 把length设小将导致所有下标大于等于新length的属性被删除
  • 使用splice来删除,尽量少用delete
  • 当属性名是小而连续的整数时,你应该使用数组;否则使用对象
  • 判断一个对象是否为数组

    typeof [] //onject
    var is_array = function (value) {

    1. return Object.prototype.toString.apply(value) === '[object Array]';

    }

  • 方法的扩充
  • 指定初始值

六、 正则表达式(略)

七、 方法

  1. 数组方法

    • concat
    • join(比用“+”好拼接这些片段要快)
    • pop
    • push
    • reverse
    • shift
    • slice(start, end)
    • sort
    • splice(start, deleteCount, item…)
    • unshift
  2. 函数方法

    • apply(thisArg, argArray)
    • toExponential(fractionDigits)
    • toFixed(fractionDigits)
    • toPrecision(precision)
    • toString(radix)
  3. 对象方法

    • hasOwnProperty(name)
  4. RegExp

    • exec(string)(正则表达式的最强大和最慢的方法)
    • test(string)返回true/false
  5. 字符串方法

    • charAt(pos)
    • charCodeAt(pos)
    • concat(string…)
    • indexOf(searchString, pos)
    • lastIndexOf(searchString, pos)
    • localeCompare(that)
    • match(regexp)
    • replace(searchValue, replaceValue)
    • search(regexp)与indexOf方法类似
    • slice(start, end)
    • split(separator, limit)
    • subString(不能处理负数,请用slice代替他)
    • toLocalLowerCase()/toLocalUpperCase()
    • toLowerCase()/toUpperCase()
    • fromCharCode(char…)

八、 代码风格

有时候觉得注释就像一个时间机器,我用它发送重要的信息给未来的我。

  • 对一个脚本应用或工具库,我只用唯一一个全局变量。
  • 每个对象都有它自己的命名空间,所以我很容易使用对象去管理代码。
  • 使用闭包能提供进一步的信息隐藏,增强我的模块的健壮性。

九、 优美的特性

精简的JS —- 主要内容:

  • 函数是顶级对象

在精简JS中,函数是有词法作用域的闭包

  • 基于原型继承的动态对象

对象是无类别的。我们可以通过普通的赋值给任何对象增加一个新成员的属性。一个对象可以从另一个对象继承成员属性。

  • 对象字面量和数组字面量

这对创建新的对象和数组来说是一种非常方便的表示法。JS字面量是数据交换格式JSON的灵感

十、 毒瘤

  • 在JS所有的糟糕特性之中,最为糟糕的一个就是它对全局变量的依赖。
  • typeof
  • parseInt
  • NaN (typeof NaN === ‘number’ //true;) 判断一个值是否可用做数字的最佳方法是使用isFinite函数,应为它会筛除NaN和Infinity,但isFinite会试图把它的运算数转换为一个数字。自定义方法:

    var isNumber = function isNumber(value){

    1. return typeof value === 'number' && isFinite(value);

    }

  • 对象

JS的对象永远不会是真的空对象,因为它们可以从原型链中取得成员属性。

写在后面

本书在豆瓣评分很高,但整本书看下来,说实话,到没感觉有特别多的感悟,可能自己学艺不精,还接受不到的大师的深层次的教导。

但收获还是有的:

  1. 代码习惯的纠正;
  2. 基础知识的强化理解,如原型链,闭包等;
  3. 某些一般性bug来源;如typeof, NaN等
  4. 实现同一功能的最优解,需考虑全面。

发表评论

表情:
评论列表 (有 0 条评论,560人围观)

还没有评论,来说两句吧...

相关阅读

    相关 JavaScript语言精粹

    一、语法 运算符优先级 . [] () 提取属性与调用函数 delete new typeof + - 一元运算符 * / % 乘法、除法、求余 + - 加法/连结、减 ...