标识符

所谓的标识符是指变量,函数属性的名字,或者函数的参数

第一个字符必须是一个字母,下划线(_)或者一个美元符号($),其他字母可以是字母,下划线,美元符号或数字。

严格模式

严格模式是为JS定义一种不同的解析与执行模型,要启用严格模式,可添加如下代码

"use strict"

添加区域

  • 想要整个脚本都启用,则加到脚本顶部
  • 想在某个函数体内启用,则在函数体内的顶部添加

添加目的

  • 消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为
  • 消除代码运行的一些不安全之处,保证代码运行的安全
  • 提高编译器效率,增加运行速度
  • 为未来新版本的Javascript做好铺垫

变量

ECMAScript的变量是松散类型的,所谓松散类型就是可以用来保存任何类型的数据

变量的定义

  • var
  • let(ES6引入)

数据类型

ECMAScript中有7种数据类型,其中6种是基本数据类型,1种是复杂数据类型
基本数据类型 String,Number,Boolean,Null,Undefined,Symbol
复杂数据类型 Object

typeof操作符

typeof操作符用于判断数据类型,可返回值有

  • string
  • number
  • boolean
  • undefined
  • object
  • function
  • symbol

typeof对于基本类型,除了null都可以显示正确类型

typeof对于对象,除了函数都会显示 object

如果我们想获得一个变量的正确类型,可以通过 Object.prototype.toString.call(xx)。这样我们就可以获得类似 [object Type] 的字符串。

只有一个值的数据类型:undefined,null

如果定义的变量准备在将来用于保存对象,那么最好将该变量初始化为null而不是其他值,这样一来,只要直接检查null值就可以知道相应的变量是否已经保存了一个对象的引用

实际上,undefined值是派生自null值的,因此对他们的相等性测试要返回true
也就是说

null == undefined // true
null === undefined // false

Boolean(any :any) :boolean

n/a 或 N/A 指不适用的意思

Number类型

八进制字面值的第一位必须是零(0),十六进制的字面值的前两位必须是0x

八进制字面量在严格模式下是无效的,会导致支持该模式的JS引擎抛出错误

在进行算数计算时,所有以八进制和十六进制表示的数值最终都将被转换成十进制的值

保存浮点数值需要的内存空间是保存整数值的两倍

isFinite()函数可用于测试一个数值是不是有穷的

NaN

NaN,即非数值,是一个特殊的数值,这个数值用于表示一个本来要返回数值的操作数未返回数值的情况,这样做可以防止抛出错误而停止代码执行

NaN特点

  • 任何涉及NaN(例:NaN/6)都会返回NaN
  • NaN与任何值都不相等,包括NaN本身

isNaN()该函数可用于确认参数是否"不是数值",该函数接收到一个值后,会尝试将这个值转换为数值,而任何不能被转换为数值的值都会导致这个函数返回true

数值转换

有三个函数可以把非数值转换为数值: Number()、parseInt()和parseFloat(),Number()适用于任何数据类型,而后者则专门用于把字符串转换成数值。

Number(any :any) :number

  • boolean: true和false分别被转换成0和1
  • number: 返回原值
  • null: 返回0
  • undefined: 返回NaN
  • string:

    • 字符串只包含数字,则将其转换成十进制数值
    • 字符串中包含有效的浮点格式,则将其转换为相应的浮点数值
    • 字符串中包含有效的十六进制格式,则将其转换为相同大小的十进制整数值
    • 字符串为空,转换成0
    • 字符串中包含除上述格式之外的字符,将其转换成NaN
  • object: 会先调用对象的valueOf()方法,然后依照前面的规则转换返回的值,如果转换的结果是NaN,则调用对象toString()方法,然后再次依照前面规则转换返回的字符串值

parseInt(str: string, base?: number) :number

  • 转换成字符串时,会忽略字符串前面的空格,直至找到第一个非空格字符,如果第一个字符不是数字字符或者负号,则会返回NaN
  • 该函数会一直解析,直到遇到一个非数字字符,则停止转换。例:parseInt('123abc') // 123
  • 遇到浮点数字符串,则会去小数取整。例parseInt('11.3') // 11
  • 如果以Ox开头且后面跟数字字符,会将其当做一个十六进制整数,如果字符串以0开头后跟数字字符,则会将其当作一个八进制数来解析
  • 第二个参数是可选的,代表进制,十六进制则填16

parseFloat(str: string) :number

  • parseFloat和parseInt类似,只不过他可以解析整数和浮点数
  • 该函数只能解析十进制值,因此它没有用第二个参数指定基数的用法

String类型

  • 字符串的特点是不可变的,也就是说,字符串一旦创建,它们的值就不能改变。要改变某个变量保存的字符串,首先要销毁原来的字符串,然后再用另一个包含新值的字符串填充该变量。

toString(base ?: number) :string

  • 该方法用于将一个值转换为字符串类型,几乎所有类型都有这个函数,除了null和undefined, 该函数有个参数,用于设置输出数值的基数。

String(any :any) :string

  • 该函数能将任何类型转换成字符串
  • 规则:

    • 如果值有toString()方法, 则调用该方法(没有参数)并返回相应的结果
    • 如果值是null,则返回"null"
    • 如果值是undefined,则返回"undefined"

Object类型

在ECMAScript中的对象其实就是一组数据和功能的集合。对象可以通过执行new操作符后跟要创建的对象类型的名称来创建。在不给构造函数传递参数时,括号可省略。
所有引用类型的值都是Object的实例

仅仅创建Object的实例并没有什么用处,关键是要理解一个重要的思想: 在ECMAScript中,Object类型是它的实例的基础,换句话说,Object类型所具有的任何属性和方法也同样存在于更具体的对象中。
每个对象都具有下列属性和方法

  • constructor: 保存着用于创建当前对象的函数,对于前面的例子而言,构造函数就是Object()
  • hasOwnProperty(propertyName: string) :boolean, 用于检查给定的属性在当前对象实例中(而不是实例的原型中)是否存在。其中,作为参数的属性名(propertyName)必须以字符串形式指定。
  • toLocaleString() :string, 返回对象的字符串表示,该字符串与执行环境的地区对应。
  • toString() :string, 返回对象的字符串表示。
  • valueOf() ,返回对象的字符串、数值或布尔值表示,通常与toString() 方法的返回值相同。

操作符

一元操作符(只能操作一个值的操作符)

递增递减操作符(++, --),包括两类,前置型和后置型

  • 前置型指将操作符放在数值变量前面,在计算数值时优先执行变量数值
  • 后置型指将操作符放在数值变量后面,在计算数值时最后执行变量数值
  • 递增递减操作符适用于任何类型的值,它遵循如下规则

    • 字符串数字类型时,先将其转换为数字值,再执行加减操作,字符串变量变成数值变量。
    • 非字符串数字类型时,将变量值设置为NaN,字符串变量变成数值变量。
    • 布尔类型时,先将其转换成0或1,再执行加减操作,布尔值变量变成数值变量。
    • 浮点类型时,直接执行加减1操作。
    • 对象时,先调用对象的valueOf()方法,已取得一个可供操作的值,然后对该值应用前述规则。如果结果是NaN,则在调用toString()方法后再应用前述规则,对象变量变成数值变量

一元加和减操作符

  • 对数值应用一元加减操作符时,代表正负号。
  • 对非数值应用一元加减操作符时,相当于调用Number()函数。

位操作符

  • ECMAScript中的所有数值都以64位格式存储,但位操作符不能直接操作64位的值,而是先将64位的值转换成32位的整数,然后执行操作,最后再将结果转换成回64位。
  • 对于有符号的整数,32位中的前31位用于表示整数的值,第32位用于表示数值的符号,0表示整数,1表示负数。
  • 负数同样以二进制码存储,但使用的格式是二进制补码,计算一个数值的二进制补码需要经过下列步骤

    • 求这个数值绝对值的二进制码。
    • 求二进制反码,即将0替换为1,1替换为0
    • 得到的二进制反码加1

按位非

该操作符用一条波浪线(~)表示,执行按位非的结果就是返回数值的反码。

按位非操作的本质:操作数的负值减1

按位与

该操作符用一个和号字符(&)表示,它有两个操作符数,同1得1,有0得0。

按位或

该操作符用一个竖线符号(|)表示,它有两个操作符数,有1得1,同0得0。

按位异或

该操作符用一个插入符号(^)表示,它有两个操作符数,只有一个1才得1,两位都是1或都是0,则返回0。

左移

该操作符由两个小于号(<<)表示,这个操作符会将数值的所有位(不包括符号位)向移动指定的位数,不足补0,左移不会影响符号位。

有符号右移

该操作符由两个大于号(>>)表示,这个操作符会将数值的所有位(不包括符号位)向移动指定的位数,不足补0,但保留符号位。

无符号右移

该操作符由三个大于号(>>>)表示,这个操作符会将数值的所有位(32位,包括符号位)向移动指定的位数,不足补0。

布尔操作符

逻辑非(!号表示)返回一个布尔值,可以应用于ECMAScript中的任何值

规则:

  • 如果操作数是一个对象,返回false
  • 如果操作数是一个空字符串,返回true
  • 如果操作数是一个非空字符串,返回false
  • 如果操作数是数值0,返回true
  • 如果操作数是任意非0数值(包括Infinity),返回false
  • 如果操作数是null,返回true
  • 如果操作数是NaN,返回true
  • 如果操作数是undefined,返回true

同时使用两个逻辑非操作符,实际上就会模拟Boolean()转换函数的行为,第一个逻辑非操作会基于无论什么操作数返回一个布尔值,而第二个逻辑非操作则对该布尔值求反,于是就得到了这个值真正对应的布尔值,真正结果与对这个值使用Boolean()函数相同。

逻辑与(&&表示)

逻辑与操作可以应用于任何类型的操作数,而不仅仅是布尔值,在有一个操作数不是布尔值的情况下,逻辑与操作就不一定返回布尔值

规则:

  • 如果第一个操作数是对象,则返回第二个操作数。
  • 如果第二个操作数是对象,则只有在第一个操作数的求值结果为true的情况下才会返回该对象。
  • 如果两个操作数都是对象,则返回第二个操作数
  • 如果第一个操作数是null,则返回null
  • 如果第一个操作数是NaN,则返回NaN
  • 如果第一个操作数是undefined,则返回undefined

逻辑与操作属于短路操作,即如果第一个操作数能够决定结果,那么就不会再对第二个操作数求值。对于逻辑与操作而言,如果第一个操作数是false,则它不会执行第二个操作数。

逻辑或(||表示)

和逻辑与相似,如果有一个操作数不是布尔值,逻辑或也不一定返回布尔值;
规则:

  • 如果第一个操作数是对象,则返回第一个操作数
  • 如果第一个操作数的求职结果为false,则返回第二个操作数
  • 如果两个操作数都是对象,则返回第一个操作数
  • 如果两个操作数都是null,则返回null
  • 如果两个操作数都是NaN,则返回NaN
  • 如果两个操作数都是undefined,则返回undefined

逻辑或也是短路操作符,如果第一个操作数的求值结果为true,就不会对第二个操作数求值了。利用逻辑或这一行为来避免为变量赋null或undefined值

乘性操作符

乘性操作符在操作数不是数值情况下会先使用Number()将其转换为数值。

乘法(*)

规则:

  • 两个数都为数值,则执行相应的乘法运算,若数值超出Infinity则返回Infinity或-Infinity
  • 若有一个操作数为NaN,则结果为NaN
  • 若Infinity与0相乘,则结果为NaN
  • 若Infinity与非0相乘,则结果为Infinity,符号取决于有符号操作数的符号。
  • 若Infinity与Infinity相乘,则结果是Infinity
  • 若一个操作数不是数值,则在后台调用Number()将其转换为数值,再应用上面规则

除法(/)

规则:

  • 两个数都是数值,则执行相应的除法运算,若数值超出Infinity则返回Infinity或-Infinity
  • 若有一个操作数是NaN,则结果是NaN
  • 若Infinity被Infinity除,则结果是NaN
  • 若0被0除,则结果是NaN
  • 若非0有限数除以0,则结果是Infinity或-Infinity
  • 若Infinity被任何非零数值除,结果是Infinity或-Infinity
  • 若一个操作数不是数值,则在后台调用Number()将其转换为数值,再应用上面规则

求模(%)

规则:

  • 两个数都是数值,则执行相应的余数运算
  • 如果被除数是无穷大值而除数是有限大的数值,则返回NaN
  • 如果被除数是有限大的数值而除数是零,则结果是NaN
  • 如果是Infinity被Infinity除,则结果是NaN
  • 如果被除数是有限大的数值而除数是无穷大的数值,则结果是被除数
  • 如果被除数是零,则结果是零
  • 若一个操作数不是数值,则在后台调用Number()将其转换为数值,再应用上面规则

加性操作符

加法

规则:

  • 两个数都是数值,执行常规的加法运算,根据下列数值返回结果

    • 若一个操作数是NaN,则结果是NaN
    • 若两个操作数都是Infinity,则结果是Infinity
    • 若两个操作数都是-Infinity,则结果是-Infinity
    • 若Infinity加-Infinity,则结果是NaN
    • (+0) + (+0) = (+0)
    • (-0) + (-0) = (-0)
    • (+0) + (-0) = (+0)
  • 若有一个操作数是字符串,则根据下列规则

    • 如果两个操作数都是字符串,则将第二个操作数与第一个操作数拼接起来
    • 如果只有一个操作数是字符串,则将另一个操作数转换为字符串,然后将两个字符串拼接起来
  • 若有一个操作数是对象、数值或布尔值,则调用他们的toString()方法取得相应的字符串值,然后再应用前面关于字符串的规则,对于undefined和null,则分别调用String()函数并取得字符串"undefined"和"null"

减法

规则:

  • 若两个数都是数值,执行常规的减法运算,并返回相应的结果
  • 若一个操作数是NaN,则结果是NaN
  • 若Infinity减Infinity,则结果是NaN
  • 若-Infinity减-Infinity,则结果是NaN
  • 若Infinity减-Infinity,则结果是Infinity
  • 若-Infinity减Infinity,则结果是-Infinity
  • (+0) - (+0) = (+0)
  • (-0) - (+0) = (-0)
  • (-0) - (-0) = (+0)
  • 若有一个操作数是字符串,布尔值,null或undefined,则先在后台调用Number()函数将其转换为数值,然后再根据前面的规则执行减法计算,若转换结果是NaN,则结果是NaN
  • 若有一个操作数是对象,则调用对象的valueOf()方法以取得表示该对象的数值,若得到的值是NaN,则减法结果就是NaN,若对象没有valueOf()方法,则调用其toString()方法并将得到的字符串转换为数值

关系操作符

指小于(<),大于(>),小于等于(<=)和大于等于(>=),皆返回布尔值
规则:

  • 若两个操作数都是数值,则执行数值比较
  • 若两个操作数都是字符串,则比较两个字符串对应的字符编码值
  • 如果一个操作数是数值,则将另一个操作数转换为一个数值,然后执行数值比较
  • 如果一个操作数是对象,则调用这个对象的valueOf()方法,用得到的结果按照前面的规则执行比较,若对象没有valueOf()方法,则调用toString()方法,并用得到的结果根据前面的规则执行比较
  • 若一个操作数是布尔值,则先将其转换为数值,然后再执行比较
  • 任何操作数与NaN比较,结果都是false

相等操作符

相等(==)和不相等(!=)——先转换再比较

规则:

  • 若有一个操作数是布尔值,则在比较相等性之前先将其转换为数值,false转换成0,true转换成1。
  • 若一个操作数是字符串,另一个操作数是数值,在比较相等性之前先将字符串转换为数值。
  • 如果一个操作数是对象,另一个操作数不是,则调用对象的valueOf()方法,用得到的基本类型值按照前面的规则进行比较
  • null和undefined是相等的。
  • 要比较相等性之前,不能将null和undefined转换成其他任何值。
  • 如果有一个操作数是NaN,则相等操作符返回false,而不相等操作符返回true,即使两个操作数都是NaN,相等操作符也返回false,因为NaN和NaN不相等
  • 如果两个操作数都是对象,则比较它们是不是同一个对象,如果两个操作数都指向同一对象,则相等操作符返回true,否则返回false。

全等(===)和不全等(!==)——仅比较不转换

null==undefined会返回true,因为它们是类似的值,但null===undefined会返回false,因为它们是不同类型的值。

条件操作符

三元运算符 variable = boolean_expression ? true_value : false_value

赋值操作符

  • 乘/赋值(*=)
  • 除/赋值(/=)
  • 加/赋值(+=)
  • 减/赋值(-=)
  • 模/赋值(%=)
  • 左移/赋值(<<=)
  • 有符号右移/赋值(>>=)
  • 无符号右移/赋值(>>>=)

所有的赋值操作符规则都一样

let num = 10
num += 1 // 等价于 num = num + 1

逗号操作符

逗号操作符可以在一条语句中执行多个操作

var num1 = 1, num2 = 2, num3 = 3; 

逗号操作符多用于声明多个变量,除此之外,还可以用于赋值,在赋值时,逗号操作符总会返回表达式的最后一项

let num = (5, 1, 4, 3, 0); // num的值为0

语句

各语言的语句都差不多,这里就不一一介绍了,这里只列举

  • if语句
  • do-while语句
  • while语句
  • for语句
  • for-in语句,迭代语句,可用来枚举对象的属性; 如果表示要迭代的对象的变量值为null或undefined,for-in语句会抛出错误,ES5虽然修正这一行为,他不会抛出错误,只是不执行循环体,但是在使用for-in循环之前,先检测确认该对象的值是不是null或undefined
  • label语句
  • break和continue语句,break和contiune的区别在于,break是退出当前循环体; continue是退出当前循环,继续执行下一个循环
  • with语句,作用是把代码作用域设置到一个特定的对象中,目的是为了简化多次编写同一个对象的工作。大量使用with语句会导致性能下降。
  • switch语句,switch中可以使用任何的数据类型,无论是字符串还是对象,case的值可以是常量,变量和表达式。switch中使用的是全等操作符,不会发生类型转换
12-08 23:30