变量
ECMAScript 的变量是松散类型的,可以用来保存任何类型的数据,换句话说,变量只是一个用于保存值得占位符而已,变量没有类型,数据才有类型!
- 使用
var
声明变量,变量为声明该变量的作用域中的局部变量。即在全局作用域中声明的变量为全局变量,在局部作用域中声明的变量为局部变量。 - 使用
var
声明的变量如果未初始化,则变量保存的值默认为undefined
。 - 对没有声明的变量直接进行赋值操作(或者说是 LHS 操作),在非严格模式下,会创建一个全局变量。但是在严格模式下,会抛出错误。
数据类型
JavaScript 的数据类型分为“基本数据类型”和“引用数据类型”两种。
- 基本数据类型:
Undefined
、Null
、Boolean
、Number
、String
和Symbol
(ES6 提出)。 - 引用数据类型:
Object
。
检测类型
typeof 操作符
对一个值使用 typeof
操作符,可能返回下列某个字符串(均为英文单词小写形式):
"undefined"
: 如果这个值未定义。"boolean"
: 如果这个值是布尔值。"string"
: 如果这个值是字符串。"number"
: 如果这个值是数值。"symbol"
: 如果这个值是符号。"function"
: 如果这个值是函数(其实函数属于对象的一种)。"object"
: 如果这个值是对象或null
。
instanceof 操作符
用于检测构造函数的 prototype
属性是否出现在某个实例对象的原型链上。
object instanceof constructor
=> true | false
《JavaScript 高级程序设计》中说:“根据规定,所有引用数据类型的值都是Object的实例。因此,在检测一个引用数据类型值和Object构造函数时,instanceof操作符始终会返回true。”
随着版本的迭代,这个说法变得不准确了,有例外了!!!
1 | var a = Object.create(null) |
Object.prototype.toString.call()
返回一个表示类型的字符串,详情请看 MDN官网。
基本数据类型
Undefined
Undefined
类型只有一个值,即特殊的 undefined
。在使用 var
声明变量但未对其加以初始化时,这个变量的值就是 undefined
。对未初始化的变量执行 typeof
操作会返回 undefined
,而对未声明的变量执行 typeof
操作同样会返回 undefined
。
除了可以对未声明的变量执行 typeof
操作之外,在非严格模式下还可以对其进行 delete
操作。除了这两种情况之外,对未声明的变量进行任何其他操作,都会抛出错误。
Null
Null
类型也只有一个值 - null
。
1 | typeof null === 'object' // true |
Boolean
Boolean
类型的字面值 true
和 false
是区分大小写的。也就是说,True
和 False
都不是 Boolean
值,只是标识符。
Number
- 八进制字面量在严格模式下是无效的,会导致支持的JavaScript引擎抛出错误。
- 浮点数值的最高精度是17位小数,但在进行算术计算时其精确度远远不如整数。
- 绝对值超过
Number.MAX_VALUE
的值会被自动转换为infinity
或-infinity
。 - 可以使用
isFinite()
函数来确定数值是否为无穷。如果不是无穷,则返回true
。 NaN
与自身都不相等,可以使用isNaN()
或Number.isNaN()
确定数值是否为NaN
。在传入数据非数值时,isNaN()
会首先调用Number()
将其转换为数值类型再进行判断,而Number.isNaN()
则会直接返回false
。Number()
用于把任何类型数据转换为数值。parseInt()
和parseFloat()
用于把字符串转换为数值。parseInt()
在转换字符串时比Number()
好用,但是最好为parseInt()
提供第二个参数(转换的基数2、8、10、16)。
String
- 任何字符串的长度都可以通过访问其
length
属性取得,包含双子节字符的可能不准确。 - 字符串是不可变的,一旦创建就不能改变,要改变某个变量保存的字符串,首先要销毁原来的字符串然后再用新的替代。
- 数值、布尔值、对象和字符串值都有
toString()
方法,并且数值的toString()
方法可以接收一个参数(数值的基数),但是null
和undefined
没有。 - 在不知道要转换值的类型时,可以使用
String()
方法。
引用数据类型
Object
ECMAScript 中的对象其实就是一组数据和功能的集合,它的属性或方法是没有顺序之分的!!!
Object 类型是所有它的实例的基础,它所具有的任何属性和方法也同样存在于更具体的对象中。Object 的每个实例都具有下列属性和方法:
constructor
hasOwnProperty(propertyName)
isPrototypeOf(object)
propertyIsEnumerable(propertyName)
toLocaleString()
toString()
valueOf()
复制变量值
在将一个值赋给变量时,如果这个值是基本数据类型,则变量中保存的是这个值本身。如果这个值是引用数据类型,则变量中保存的只是该值的一个引用(通过引用,可以在内存中找到这个引用数据类型的值)!
1 | // =================================================== |
传递参数
ECMAScript 中所有函数的参数都是按值传递的。简单来说就是数据进行复制,然后传递给给函数作为参数。
语句
for-in语句
ECMAScript 对象的属性没有顺序。因此,通过 for-in
循环输出的属性名的顺序是不可预测的。
for-in
不能对 null
和 undefined
进行迭代。
switch语句
可以在 switch 语句中使用任何数据类型(在很多其他语言中只能使用数值),并且每个 case 的值不一定是常量,可以是变量,甚至是表达式。
switch对 case 进行匹配时,遵循的是 ===
严格相等。
函数
理解参数
首先说明我的观点,不推荐使用 arguments
!!!
ECMAScript 中的函数参数是用一个数组来表示的,可以通过 arguments
对象来访问这个数组,arguments
是一个类数组对象。
关于 arguments
和 命名参数
之间是如何相互影响的,《JavaScript高级程序设计》与《深入理解ES6》的说法有些矛盾,我在谷歌浏览器中简单的试了一下,他们之间的同步关系好像是双向的。
没有重载
ECMAScript 中的函数没有重载,如果声明了多个同名函数,后面的会覆盖前面的。
垃圾收集
JavaScript 中的变量分为全局变量和局部变量,其中全局变量一直存在,不会被清除。
而局部变量只在函数执行的过程中存在,当函数执行结束后,局部变量会被自动清除。
当然如果存在闭包的话,局部变量被清除的时机需要取决于闭包。