语法专题
数据类型的转换
JavaScript 是一种动态类型语言,变量没有类型限制,可以随时赋予任意值。
下面的例子,x是数值还是字符串取决于y是true
还是false
。因此在编译期间无法知道x的类型,只有在运行时才可以确定。
var x = y ? 1 : 'a';
强制转换
强制转换包括:Number()、Boolean()、String()。
Number函数
Number()函数可以将任意类型的值转换为数值型。对于基本类型的数值采取以下措施:
//字符串如果可以转换就是数值,否则为NaN
Number('324') // 324
Number('324abc') // NaN
//布尔值就是true:1,false:0
// undefined:转成 NaN
Number(undefined) // NaN
// null:转成0
Number(null) // 0
值得一提的是,parseInt和Number的策略不同,pareInt是逐个解析字符,而Number会解析整个字符串
parseInt('42 cats') // 42
Number('42 cats') // NaN
对于对象来说:
(1)首先会调用对象的valueof方法,
(2)如果返回的是仍然是对象,就会改为调用对象的toString方法,对返回值进行Number方法,值得一提的是如果返回值不是基本类型的值会报错。
(3)如果返回的不是对象,就会对对象valueOf方法的返回值进行Number方法。
var obj = {x: 1};
Number(obj) // NaN
// 等同于
if (typeof obj.valueOf() === 'object') {
Number(obj.toString());
} else {
Number(obj.valueOf());
}
String函数
(1)原始类型
//布尔类型,转换为'false'与'true'
//数值类型,转换为相应的字符串'123'
//undefined,转换为'undefined'
//null,转换为'null'
(2)对象
与Number方法相似,只不过是调换了toString
方法和valueOf
方法的顺序。
String({a: 1})
// "[object Object]"
// 等同于
String({a: 1}.toString())
// "[object Object]"
Boolean函数
Boolean函数除了以下五个值以外,返回值都是true
,切记对对象进行Boolean函数,返回值也是true
。
Boolean(undefined) // false
Boolean(null) // false
Boolean(0) // false
Boolean(NaN) // false
Boolean('') // false
自动转换
1.自动转换为布尔值:遇到需要布尔值结果的时候如if语句,三元运算符,
// 写法一
expression ? true : false
// 写法二
!! expression
//写法三
if(expression)
2.字符串的自动转换
主要发生在字符串的加法运算时。当一个值为字符串,另一个值为非字符串,则后者转为字符串。
具体规则是,先将复合类型(基本类型和对象)的值转为原始类型的值,再将原始类型的值转为字符串。
'5' + 1 // '51'
'5' + true // "5true"
'5' + false // "5false"
'5' + {} // "5[object Object]"
'5' + [] // "5"
'5' + function (){} // "5function (){}"
'5' + undefined // "5undefined"
'5' + null // "5null"
3.自动转为数值
除了加法运算符(+)有可能把运算子转为字符串,其他运算符都会把运算子自动转成数值。
'5' - '2' // 3
'5' * '2' // 10
true - 1 // 0
false - 1 // -1
'1' - 1 // 0
'5' * [] // 0
false / '5' // 0
'abc' - 1 // NaN
null + 1 // 1
undefined + 1 // NaN
注意 null转为数值型为0,而undefined为NaN。
错误处理机制
常规六种错误
JavaScript 提供Error对象来提示错误信息。Error对象一般包括以下几个属性:
- message:错误提示信息
- name:错误名称(非标准属性)
- stack:错误的堆栈(非标准属性)
SyntaxError
对象是解析代码时发生的语法错误。
// 变量名错误
var 1a;
// Uncaught SyntaxError: Invalid or unexpected token
// 缺少括号
console.log 'hello');
// Uncaught SyntaxError: Unexpected string
ReferenceError
对象是引用一个不存在的变量时发生的错误。
// 使用一个不存在的变量
unknownVariable
// Uncaught ReferenceError: unknownVariable is not defined
RangeError
对象是一个值超出有效范围时发生的错误。主要有几种情况,一是数组长度为负数,二是Number对象的方法参数超出范围,以及函数堆栈超过最大值。
// 数组长度不得为负数
new Array(-1)
// Uncaught RangeError: Invalid array length
TypeError
对象是变量或参数不是预期类型时发生的错误。
(1)对原始类型的值使用new命令
(2)使用对象没有的方法
new 123
// Uncaught TypeError: number is not a func
var obj = {};
obj.unknownMethod()
// Uncaught TypeError: obj.unknownMethod is not a function
URIError
对象是 URI 相关函数的参数不正确时抛出的错误。
自定义错误
这里自定义了一个错误对象UserError,并让他继承自Error对象。
function UserError(message) {
this.message = message || '默认信息';
this.name = 'UserError';
}
UserError.prototype = new Error();
UserError.prototype.constructor = UserError;
可以通过new语句来新建该错误。
new UserError('这是自定义的错误!');
处理错误的语句
1.throw
语句
通过throw语句,可以在错误的情形下抛出错误。
if (x <= 0) {
throw new Error('x 必须为正数');
}
对于 JavaScript 引擎来说,遇到throw语句,程序就中止了。
2.try...catch
语句
一旦发生错误,程序就中止执行了。JavaScript 提供了try…catch结构,允许对错误进行处理,选择是否往下执行。
try {
f();
} catch(e) {
// 处理错误
}
与java类似,在try中执行可能出错的语句,然后一旦出错,就进入catch语句。
3.finnaly
语句
try...catch
结构允许在最后添加一个finally
代码块,表示不管是否出现错误,都必需在最后运行的语句。值得一提的是,如果try
或catch
结构中有return
语句的话,return
语句执行是排在finally
代码之前,只是等finally
代码执行完毕后才返回。
var count = 0;
function countUp() {
try {
return count;
} finally {
count++;
}
}
countUp()
// 0
count
// 1
上述代码说明了,return
语句 是在finally
代码块之前执行的(countup
返回的是0),但是要等finally
代码执行完才返回(count
确实自增了)。
语法规范
和java不同的是,有些不使用分号的情况:
(1)for 和 while 循环
for ( ; ; ) {
} // 没有分号
while (true) {
} // 没有分号
(2)分支语句
if (true) {
} // 没有分号
switch () {
} // 没有分号
try {
} catch {
} // 没有分号
(3)函数的声明语句
function f() {
} // 没有分号
但函数表达式还是需要分号的
var f = function f() {
};
console 控制台
console的常见用途有两个。
- 调试程序,显示网页代码运行时的错误信息。
- 提供了一个命令行接口,用来与网页代码互动。
我们常用的包括console.log
、console.warn
、console.error
三个方法来作为调试的信息。区别就是标示程度。
console还有dir
方法,该方法对于输出 DOM 对象非常有用,因为会显示 DOM 对象的所有属性。但还没学DOM,所以这里就记录下吧。简单理解为易于阅读。
console.log({f1: 'foo', f2: 'bar'})
// Object {f1: "foo", f2: "bar"}
console.dir({f1: 'foo', f2: 'bar'})
// Object
// f1: "foo"
// f2: "bar"
// __proto__: Object
一些常用命令
(1)$_
属性返回上一个表达式的值。
2 + 2
// 4
$_
// 4
(2)getEventListeners(object)
getEventListeners(object)方法返回一个对象,该对象的成员为object登记了回调函数的各种事件(比如click或keydown),每个事件对应一个数组,数组的成员为该事件的回调函数。
(3)keys(object)
,values(object)
分别返回一个数组,保存着对象的键与值。
var o = {'p1': 'a', 'p2': 'b'};
keys(o)
// ["p1", "p2"]
values(o)
// ["a", "b"]
(4)monitorEvents(object[, events])
,unmonitorEvents(object[, events])
monitorEvents(object[, events])方法监听特定对象上发生的特定事件。事件发生时,会返回一个Event对象,包含该事件的相关信息。unmonitorEvents方法用于停止监听。