《Javascript语言精粹》笔记

前言:

我细看了这本书的前几章,并且详细记录和扩展了相关的知识点。往后的一些章节,有一部分是我已经熟知的,有一部分是比较老旧的,所以就没再进行详细阅读和记录。

1、语法

whitespace

whitespace通常没有意义,有时候需要用来分隔字符序列,例如:var a = 1,中的标识符var和a中间的空格。

注释

使用//来注释相对于用/* */来注释会更安全,因为可能会与正则表达式中的*一起产生问题。

个人觉得/* */这种方式分割区块会更清晰,而//专门用于句注释会更方便。

标识符

标识符被用于语句、变量、参数、属性名、运算符和标记(例如for循环标记)。不能使用JS的保留字命名变量、参数,使用点运算符来提取对象属性时,对象属性也不能用作保留字,不过使用object[property]提取时是可以的。

数字

JS 只有一种数字类型,基于 IEEE 754 标准的双精度64位二进制格式的值。由于 JS 没有分离出整数类型,所有在 JS 中 1 === 1.0

NaN 是一个数值,它标识一个不能产生正常结果的结果。NaN 不等于任何值,甚至是它自己。

字符串

JS中的字符串被包在一堆''""当中,可以包含0到多个字符。

反斜线符号是转义字符。转义符用来转义一些不允许被直接插入到字符串中的字符,比如/'"、制表符等。

语句

语句:一段可执行的代码,并且不总有值

在 WEB 浏览器中,每个<script>标签都会提供一个被编译且立即执行的编译单元。一个编译单元包含一组可执行的语句。

编译单元就像是一个积木,通常用“链接器”来让他们一个个堆起来。但是在JS中缺少“链接器”,所以JS选择把所有编译单元都抛到一个公共的全局空间中,以达到“链接器”的效果。

JS语句通常是从上至下运行的。可以通过条件语句if switch 、循环语句 while for do 、 强制跳转语句 break return throw 和函数调用来改变执行序列。

while (expression) {block}

do {blcok} while(expression);

for (initalization;condition;increment) {block}

for (prop in property){block}

whiledo的区别是,while语句可能一次都不会执行,而do至少会执行一次。

for in语句可以用来枚举对象的属性。

JS不允许在return与表达式之间换行、不允许在break和标签之间换行。

try {block} catch(name) {block}

throw(expression)

throw语句可以抛出一个异常,如果throw语句在函数中使用,则该函数调用会被放弃,控制流跳转到调用该函数的try语句的catch语句中。

表达式

表达式:可以被求值的代码,并且总有结果

字符串、数字、变量、内置值、以new开头调用表达式、以delete开头的属性提取表达式、包在圆括号中的表达式、以一个前置运算符为前导的表达式…

JS中的表达式和运算符

基本关键字和常用表达式

this: 指向函数的执行上下文。

fuctionfunction 关键字定义了函数表达式。

classclass 关键字定义了类表达式。

function*:function* 关键字定义了一个 generator 函数表达式。

yield:暂停和恢复 generator 函数。

yield*:委派给另外一个generator函数或可迭代的对象。

[]:数组字面量语法。

{}:对象字面量语法。

/ab+c/i:正则字面量语法。

():用来控制表达式中的运算优先级,括号中表达式会求值并被返回。

Left-hand-side 表达式

new: 创建对象的实例,new constructor[([arguments])]

super: 调用父类的构造器。

. []: 访问对象属性或方法。

注:当我们提及一个对象的属性时,会对属性和方法之间做个对比。然而,属性和方法之间的区别并不大。一个方法就是一个可以被调用的属性而已。

...obj:展开运算符可以将一个可迭代的对象在函数调用的位置展开成为多个参数,或者在数组字面量中展开成多个数组元素。

自增和自减运算符

A++:后置自增运算符,在递增前返回数值。

++A:前置自增运算符,在递增后返回数值。

A--:后置自减运算符,在递减前返回数值。

--A:前置自减运算符,在递减后返回数值。

一元运算符

一元运算符:只对一个表达式执行操作。

delete: 删除对象的属性。

void:对表达式进行求值,然后返回undefined

typeof: 判断对象类型。

+: 一元加运算符,将操作值转换为数值,用这个符号可以转换非数值类型为数值。

-:一元减操作符,将操作值转换为Number类型并取反。

~:按位非操作符,对任一数值x进行按位非操作的结果为-(x + 1),~5 的结果是 -6,和indexOf一起使用~str.indexOf(searchFor)

!:逻辑非运算符

算数运算符

+-*/%:加、减、乘、除、取模,加可以用于字符串拼接。

关系运算符

in:判断对象是否用用给定属性。

instanceof:判断一个对象是否是另一个对象的实例。

<><=>=:小于、大于、小于等于、大于等于。

逗号操作符

,:对它的每个操作数求值(从左到右),并返回最后一个操作数的值。var语句中的逗号并不是逗号操作符,它是var语句中的一个特殊符号,用于把多个变量声明结合成一个。

字面量

字面量是由语法表达式定义的常量

在JS中有各种字面量,这些字面量都是按字面意思给出的固定的值,而不是变量。

  • 数组字面量

    数组字面量是一对方括号中包裹着0或多个表达式的列表。当你使用数组字面量创建数组时,数组会以被指定的值作为数组元素进行初始化,而长度就是元素的个数。

    数组字面量同时也是一个数组对象初始化器,对象初始化器还包括{}

  • 对象字面量

    对象字面量使用{}来表示,花括号中可以写如0或多个“属性:值”对。

  • 正则字面量

    使用/abc+c/双斜杠来表示

  • 整数字面量

    整数可以用十进制、十六进制、八进制、二进制表示

  • 浮点数字面量

    浮点数语法:[(+|-)][digits][.digits][(E|e)[(+|-)]digits]

  • 布尔值字面量

    truefalse

  • 字符串字面量

    使用''""包裹0或多个字符,字符被限定在同种引号之间。

2、对象

JS中的对象是可变的键控集合(这是什么意思?)。

两个独立声明的对象永远不会相等,即使他们拥有相同的属性。

JS中创建对象的方法:

  • 对象字面量{} 可以方便的创建对象,这是后面出现的一种更简便的方法。

  • 构造函数 可以定义对象的类型,需要通过new关键字来创建对象

  • Object.create() 语法:Object.create(proto, [ propertiesObject ])

原型

每个对象都会链接到一个原型对象,并从原型对象中继承属性。

所有通过对象字面量创建的对象的原型都指向Object.prototype,它是JS中的基础对象。

原形链在更新的时候是不起作用的,当我们修改某个对象时,不会触及该对象的原型。原形链只有在检索的时候才会被用到,当对象中没有属性名的时候,会顺着原型链像上检索,直到查到Object.prototype为止,如果还是没有就会返回undefined。这个过程称之为委托

删除

使用delete可以帮助你删除对象的属性

3、函数

函数包含一组语句,它们是JS的基础模块单元,用于代码复用、信息隐藏和组合调用。函数用于指定对象的行为。一般来说,所谓编程,就是将一组需求分解成一组函数与数据结构的技能。

JS中函数就是对象。

对象是“名/值”对的集合并拥有一个连到原型对象的隐藏连接。

字面量对象连接到Object.prototype

{} –> Object.prototype

函数对象连接到Function.prototype

function foo(){} –> Function.prototype –> Object.prototype

闭包:通过函数字面量创建的函数对象包含一个连接到外部上下文的连接,这被称为闭包。

this在不同调用方式中的表现

  • 方法调用模式 当以函数被保存为对象的属性时,我们称之为方法。当方法被调用时,this指向的是该对象。this到对象的绑定发生在方法被调用的时候。通过this能够访问对象上下文的方法,称之为公共方法。

  • 函数调用模式 函数如果不是对象的属性,就会被当作函数来调用。被当作函数调用的时候,this默认指向全局对象。

  • 构造器调用模式 一个函数如果结合new来使用,那就是构造器函数。 JS是一门基于原形继承的语言,而大多数面相对象语言都是基于的语言。 而构造函数中的this,在通过new调用后,会创建一个连接到该函数的prototype成员的新对象(实例化对象),this则会绑定在这个对象上。

  • apply调用模式 apply可以动态的改变this的指向,它是函数对象的一个方法。apply可以接收两个参数,第一个就是要绑定的this的值,第二个就是一个参数数组。与其十分相似的方法是callcallapply唯一的不同是传入参数的方式。apply是传入参数数组,而call是依次传入参数用逗号分割。

参数

当函数被调用时,函数会被默认分配一个arguments参数,通过这个参数我们可以有序访问被传入到函数中的参数。arguments是一个类似数组的对象,拥有length属性,但却没有数组的方法,不过可以把arguments转换为真正的数组。

返回

函数在执行时,如果指定了return,则会返回执行的结果。如果没有指定return,则默认返回undefined。当使用new调用函数时,如果没有指定return,默认返回this,即this指向的对象。

扩充类型的功能

因为JS是基于原型继承,所以我们可以通过给原型对象添加方法来扩充其的功能。

递归

把一个问题分解成一组相似的子问题,每一个都用一个寻常解去解决。

作用域

作用域控制着变量与参数的可见性与声明周期。在很多语言中都拥有块级作用域,在块级作用域中定义的变量在代码块外是不可见的。并且在代码块结束后,代码块中变量会被释放。

而在JS中,没有块级作用域这个概念。JS中只有函数作用域这个概念。

闭包

闭包是指这样的作用域,它包含一个函数,这个函数可以调用被这个作用域封闭的变量、函数、闭包等内容。通常我们通过闭包所对应的函数来获得对闭包的访问。

回调

回调是把一个函数当作另一个函数的参数进行调用,当外部函数执行完毕时再执行被当作参数传递的内部函数,这个过程就是回调。被当作参数的函数就是回调函数。

模块

模块是一个提供接口却隐藏状态与实现的函数或对象。

模块模式一般形式是:一个定义了私有变量和函数的函数;利用闭包创建可以访问私有变量和函数的特权函数;最后返回这个特权函数,或者把它们保存到一个可以访问到的地方。

模板方法通常结合单例模式使用。JS的单例就是用对象字面量创建对象,并且对象的属性在生命周期中不会发生变化。它通常作为工具为程序其他部分提供功能支持。

模块也能用来产生安全的对象,在闭包作用域中写入私有变量,再通过闭包函数返回出去。这样除了访问返回的方法,是无法用其他方式改变私有变量的。

级联

在对象的方法中返回this,这样能达到方法级联运行object.do1().do2().do3()的效果。

柯里化

柯里化允许我们把函数与传递给它的参数相结合,产生一个新的函数。把多参数函数转换为一系列单参数函数并进行调用的技术。

记忆

不要重复计算已经得到的结果,把已计算过的结果缓存起来。

4、继承

伪类

在其他基于类的语言中,对象是类的实例,并且类可以从另一个类继承。JS是一门基于原型的语言,这意味着对象直接从其他对象继承。

因为JS语言没有提供一种方法去确定哪个函数是打算用来做构造器的,所有每个函数都有prototype对象。

原文:大专栏  《Javascript语言精粹》笔记


猜你喜欢

转载自www.cnblogs.com/petewell/p/11615196.html