JavaScript的变量类型是动态类型, 因此语言中会有很多强制转换的情况发生. 运算符实际上是一种特殊的函数.

动态类型 Dynamic Typing:

在JavaScript中,定义一个变量时,不需要显式声明变量的类型,JS引擎在代码运行时会自动识别变量类型,所以在程序执行时,一个变量在不同时间可以拥有不同的类型.

Java, C#的变量类型是静态的(Static Typing), 即需要显式声明变量类型,而且在程序执行过程中类型不可改变.

Static Typing:

bool isNew = "hello"; 会提示错误.

Dynamic Typing:

1
2
3
var isNew = true; // 没有错误
isNew = 'yup!';
isNew = 1;

原始类型 Primitive Types:

原始类型(定义): A type of data that represents a single value. (在JS中也就是: 不是对象,不存在方法)

JS中有6种原始类型:

1. undefined: (represents lack of existence), undefined是JavaScript语言中的一个特殊值,变量的值是undefined表明这个变量未被赋值.

不要手动将变量值设为undefined!! 因为在调试时会出现混乱,不知道是自己将变量设置为undefined还是变量未被赋值.

2. null: (also represents lack of existence), 可以手动将变量值设置为null.

3. boolean

4. number: 在JavaScript中只有这一种类型()来表示数字, 不像其他编程语言, 有整数, 浮点数, 定点数等.

5. string

6. symbol: ECMAScript 2015中新加入的类型

运算符 operators

运算符实际上是一种特殊的函数, 只是在句法结构上与一般的函数不同, 一般来说, 运算符接受两个参数, 返回一个结果.

1
var a = 3 + 4;

+是运算符, 实际上是一个函数
对于上述代码, JS引擎实际是这样执行的:

1
2
3
function +(a,b){
return // 返回 a + b 的结果
}

那么如果想要调用这个函数, 就该这样做 +(3,4);, 但是这样太过麻烦, 为了简便JS引擎实现了 中缀标记法(infix notation), 于是就可以用这种形式调用函数 3+4;

运算符优先级

运算符优先级指哪个运算符会被先调用, 即最先执行.

关联性Associativity

关联性决定了拥有相同优先级的运算符的执行顺序, 如果与左边关联性较强, 那么先执行左边的部分, 反之同理.

具体的优先级和关联性详见Operator Precedence中的表格.

强制转换 coercion

将某一类型的变量强制转换成另一种类型, 因为JS是Dynamic Typing, 所以强制转换在语言中很常见. 强制转换包括隐式强制转换和显式强制转换. 详见

隐式强制转换:

1
2
3
var a = 1 + '2';
console.log(a);
//'12'

在内存中1'1'完全不同, 但在函数执行过程中JS引擎将数字1强制转换为字符. 在一些其他语言中会抛出错误.

1
2
3
4
5
6
7
8
9
10
11
12
console.log(3 < 2 < 1);
// true
// 因为优先级相同, `<`是左关联性较强的操作符, `3 < 2`返回false
// 所以实际上是 `false < 1` 的比较, 布尔值会被强制转换为数字
// false被强制转换为0, `0 < 1` 自然返回true

console.log(1 < 2 < 3);
// true
// 返回true的原因并不是1小于2小于3
// 而是 `1 < 2` 返回true
// true被强制转换为1, `1 < 3`
// 因此最终结果为true
1
2
3
4
5
6
7
8
9
10
null == 0;
// false
null < 1;
// true
false == 0;
// true
"" == 0;
// true
"" == false;
// true

强制转换功能强大, 但也很危险. 用 ===(严格相等) 来比较值不会进行强制转换, 因此在比较值时, 多用 === 而不是 ==.

JavaScript中的相等性判断

显式强制转换:

1
2
3
4
5
6
7
8
9
10
11
12
Number(true);
// 1
Number(false);
// 0
Number(undefined);
// NaN
Number(null);
// 0
Boolean(0);
// false
Boolean(1);
// true

存在性和布尔值

表示不存在含义的值会被强制转换为false, 如undefined, null, "".
因此可以利用coercion判断某个变量的存在性.

1
2
3
4
5
6
var a;

if (a) {
console.log('something is there.');
}
// 不会有输出, 因为a被强制转换为false.

如果a为undefined, null, ""中任意一个, 程序就不会有输出, 有个例外情况, 若a的值为0, 程序也不会有输出, 但0并不是不存在.

可以这样改进:

1
2
3
4
5
6
7
var a;

a = 0;

if (a || a === 0) {
console.log('something is there.');
}

默认值

1
2
3
4
5
6
7
8
9
function greet(name){
console.log('Hello '+ name);
}
greet('Tony');
// 'Hello Tony';
greet();
// 若不传入参数, 很多其他编程会抛出错误
// 但是JavaScript这样输出:
// 'Hello undefined';

可以这样改进:

1
2
3
4
5
function greet(name){
name = name || '<Your name here>';
console.log('Hello '+ name);
}
greet();

运用ES6的改进方式:

1
2
3
4
const greet = (name='<Your name here>') => {
console.log(`Hello ${name}`);
}
greet();

参考