JavaScript 基础¶
注释¶
- 单行注释
//
- 多行注释
/* */
变量¶
变量声明¶
对值的具名引用。没有赋值的变量的值是undefined
。
使用var
来声明变量;不使用var
的声明可被执行。
var a = 1 + 3;
- 变量具有动态类型。
- 变量提升 所有使用
var
声明变量的语句都会被提升到代码的头部,并先执行。
在区块中的变量¶
对于var
声明的变量来说,区块(Block)不构成单独的作用域(Scope)。
{
var a = 1;
}
a; // 1
命名规范¶
- 第一个字符可以是任意Unicode字母,以及美元符号
$
和下划线_
。 - 第二个字符以及其后字符还可以是数字。
数据类型¶
JavaScript中定义了7种数据类型:
number
数值string
字符串boolean
布尔值undefined
未定义null
空值object
对象,包括狭义的对象object
,数组array
以及函数function
symbol
符号,ES6新增类型
typeof
¶
可以使用typeof
运算符来判断一个变量的类型,返回“number”等字符串。
因此可以用typeof
来检查一个没有声明的变量而不报错。
由于历史原因,typeof null
返回“object”。
null
与undefined
¶
if语句中两者都会自动被转换成false
,使用==
会报告两者相等。
Dart语言中只有null
,没有undefined
。
null表示空对象,转换成数值时表示0;undefined
表示未定义,转换成数值时表示NaN
。
调用函数时,未提供参数时,该参数返回undefined
;函数无返回值时返回undefined
。
布尔值¶
以下值被自动转换为false
- undefined和null
- false
- 0
- NaN
- 空字符串 ''
使用Boolean()
进行强制类型转换
数值¶
在Javascript内部,所有数值(包括整数)使用64位浮点数储存
由于64位浮点数的特性,绝对值小于2的53次方的整数都能精确地表示,即对15位的进制数都能精确处理
数值范围是[0, Infinity);Number
对象提供MaxValue
和MinValue
方法。
表示数值的字面值
- 十进制:没有前导0的数值。
- 八进制:有前缀0o或0O的数值,或者有前导0、且只用到0-7的八个阿拉伯数字的数值。
- 十六进制:有前缀0x或0X的数值。
- 二进制:有前缀0b或0B的数值。
正零与负零¶
toString()
方法都返回0
唯一有区别的场合是作为分母时分别得到+Infinity
和-Infinity
NaN¶
NaN参与的运算结果都是NaN
NaN是唯一的不等于自身的值,(NaN == NaN) === false
, (NaN === NaN) === false
与数值相关的全局方法¶
-
parseInt()
用于将字符串转换成整数 自动去除空格,返回NaN或转换后的数值 注意到 对于那些会自动转为科学计数法的数字,parseInt会将科学计数法的表示方法视为字符串,因此导致**一些奇怪的结果**。parseInt(1000000000000000000000.5) // 1 // 等同于 parseInt('1e+21') // 1 parseInt(0.0000008) // 8 // 等同于 parseInt('8e-7') // 8
还可以附带第二个参数进行进制转换,
parseInt('1010', 2);
2.parseFloat()
3.isNaN()
,isFinite()
使用Number()
进行强制类型转换
字符串¶
使用单引号或双引号均可,一般约定使用单引号,以与html相区分。
反斜线转义
\HHH
八进制转义\xHH
十六进制转义\uXXXX
Unicode转义
可以使用方括号语法访问字符串中的单个字符,但*无法改变*单个字符。
字符串具有length
属性
使用String()
进行强制类型转换
Base64¶
btoa()
, atob()
对象¶
无序的键值对的集合
{
foo: 'hello',
bar: 'world'
};
键名又称属性。最后一个属性后面可以添加逗号
所有的键名都是字符串,因此加引号与否无影响。(数值键名会被自动转换为字符串,如果键名不满足作为标识符的条件,则必须加上引号)
var obj = {
1p : 'Page 1', // 报错
h + w: 'H and W' // 报错
};
var obj = {
'1p': 'Page 1',
'h + w': 'H and W'
}
键值可以是任何数据类型,包括函数。
属性的读取与赋值¶
点运算符或方括号运算符均可。
方括号运算符接受;数值键名不接受点运算符。
查看所有属性,可以使用Object.keys()
。
使用delete
删除属性,成功后返回true
。delete
不能删除继承的属性。
判断属性是否存在,使用in
运算符。
遍历可遍历的属性(包括继承的属性),使用for ... in
循环。
for (var key in obj) {
console.log(key);
console.log(obj[key]);
}
with¶
建议不使用with
语句。
作用是操纵同一对象的属性时提供书写的方便。
对象or表达式¶
{ foo: 123 }
为了消歧义,如果行首是括号,解释为对象;否则为语句块。
- 对象
({ foo: 123 }) // 123
- 语句块
{ foo: 123 } // {foo: 123}
函数¶
声明函数由三种方式
- function命令声明
- 函数表达式形式的声明
- 使用Function构造函数
函数表达式形式的声明,若有var f = function k() {...}
,则名称k
只在函数内部有效。
函数若重复声明,后一次将覆盖前一次的声明,且由于变量提升和函数声明提升,前一次声明任何时候都是无效的。
函数的属性和方法¶
name
属性 返回函数的名字;若函数为表达式形式,且为匿名函数,则返回变量的名字;若为具名函数,则返回此function
关键字之后的函数名length
属性 返回函数定义时的参数个数toString()
方法 返回函数的源代码,包括其中的注释
作用域¶
函数执行时的作用域,是定义时的作用域而不是调用时所在的作用域。函数体内部声明的函数,作用域绑定函数体内部。
参数¶
Js允许省略参数而不报错,可以为参数传入undefined
;支持默认参数。
参数的传递方式如下:
- 原始数据类型(数值、字符串、布尔值)按值传递 pass by value
- 对象按址传递 pass by reference
如果出现同名参数,则按名存取时取后一个参数名;访问前一个可以使用arguments
关键字。
不定参数,可以通过arguments
变量来获取,也可以使用三句点语法。
function add(...x) {
return x.reduce((m, n) => m + n);
}
支持拓展参数,即通过...
操作符将数组作为函数的参数使用而不需要使用apply()
。
arguments对象¶
arguments对象不是一个数组,但可以通过数值下标访问和具有length
属性;严格模式下对arguments
的修改是无效的。
闭包¶
“定义在函数内部的函数”,可以“记住诞生的环境”。
闭包的两大用处是:
- 可以读取函数内部声明的变量
- 可以使闭包诞生的环境持续存在
function createIncrementor(start) {
return function () {
return start++;
};
}
var inc = createIncrementor(5);
inc() // 5
inc() // 6
inc() // 7
立即调用的函数表达式 IIFE¶
推而广之,任何让解释器以表达式来处理函数定义的方法,都能产生同样的效果,比如:
(function () { /* code */ })();
+function() { /* code */ }();
eval
对表达式求值¶
接受字符串作为参数,并将此字符串作为函数执行。
严格模式中,eval
中声明的变量,不会影响到全局作用域,但仍可以读写当前作用域内的变量。
当eval
使用别名调用时,其作用域为全局作用域。
数组¶
按次序排列的一组值,数组是特殊的对象,其键名是依序排列的一组值。
Js数组使用32位整数保存数组长度length
,最大长度为4294967295。length
属性是可写的,总是比最大的数字键值多一,修改length
时,数组会根据值删除已有元素或增加空位。读取空位时返回undefined
。
可以使用in
运算符来检查数组的键,如果数组中的某位置是空位,in
返回false
。
空位与undefined
是不一样的,遍历数组时,空位会被跳过而undefined
则不会。
类似数组的对象¶
具有length属性的对象是类似数组的对象,如函数的arguments
。
可以使用Array.prototype.slice.call()
方法将类似数组的对象转换为数组。
数据类型的转换¶
强制类型转换¶
Number()
¶
对于原始类型的值规则如下:
- 数值转换后为原来的值。
- 可以解析为数值的字符串,转换为相应的数值;否则返回
NaN
(注意与parseInt()
函数的区别,324abc
返回NaN
);空字符串''
返回0。 undefined
转换为NaN
,null
转换为0。- 对对象通常返回
NaN
,但包含单个值的数组除外。
注意,Number()
与parseInt()
都自动过滤前导空格后后置空格。
Number()
方法的转换机制是先尝试调用valueOf()
,然后尝试toString()
;尝试均失败后报错。
String()
¶
将任意类型的值转换为字符串。
- 数值转换为相应字符串。
- 字符串转换后仍为原来的值。
true
转换为'true'
,false
转换为'false'
。- 对象返回代表对象的字符串,如
[object Object]
;
String()
方法的转换机制与Number()
相似,只是先尝试调用toString()
,然后尝试valueOf()
。尝试失败后则报错。
Boolean
¶
除以下内容外转换结果均为true
。
undefined
null
0
,-0
,+0
NaN
''
因此所有对象的转换结果都为true
,包括Boolean(new Boolean(false))
对象。
自动转换¶
预期为何种类型,就自动转换为何种类型。
含有字符串的二元加法运算,算子均转换为字符串。其他运算符将算子转换为数值,存在将两侧的算子都转换为数值的情况。
注意一元运算符也会将算子转为数值
+true; // 1
+'abc'; // NaN