前段时间忙,好久没更新了,继续梳理基础知识
这期总结的是JS的基本概念
标识符
所谓的标识符是指变量,函数属性的名字,或者函数的参数
第一个字符必须是一个字母,下划线(_)或者一个美元符号($),其他字母可以是字母,下划线,美元符号或数字。
严格模式
严格模式是为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
对于 null 来说,虽然它是基本类型,但是会显示 object,这是一个存在很久了的 Bug,因为在 JS 的最初版本中,使用的是 32位系统,为了性能考虑使用低位存储了变量的类型信息,000 开头代表是对象,然而 null 表示为全零,所以将它错误的判断为 object。虽然现在的内部类型判断代码已经改变了,但是对于这个 Bug 却是一直流传下来。
如果我们想获得一个变量的正确类型,可以通过 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 指不适用的意思
数据类型 | 转换为true的值 | 转换为false的值 |
---|---|---|
Boolean | true | false |
String | 任何非空字符串 | **(空字符串) |
Number | 任何非零数字值(包括无穷大) | 0和NaN |
Object | 任何对象 | null |
undefined | n/a | undefined |
null | n/a | null |
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中使用的是全等操作符,不会发生类型转换
js里面的函数没有签名,函数重载也不可能实现,即不能定义相同名字的函数,通过参数个数的多少来调用相应的函数