JavaScript基本语法(二)
1、前文知识连接
- 第一篇:
JavaScript基本语法(一)
2、JavaScript条件判断
- 单层 JavaScript使用if () { … } else { … }来进行条件判断。例如,根据年龄显示不同内容,可以用if语句实现如下:
var age = 23;
if (age >= 22) { // 如果age >= 18为true,则执行if语句块
alert('找到工作了吗你?');
} else { // 否则执行else语句块
alert('别玩了,快毕业了,马上找不到工作了');
}
else语句是可选的。如果语句块只包含一条语句,那么可以省略{},与其他语言类似。
代码语言:javascript复制var age = 23;
if (age >= 22)
alert('找到工作了吗你?');
else
alert('别玩了,快毕业了,马上找不到工作了');
但为了后续修改的便利,还是建议写上{}。
- 多行条件语句 与其他语言类似。
var age = 3;
if (age >= 18) {
alert('带专');
} else if (age >= 6) {
alert('职高');
} else {
alert('幼儿园');
}
请注意,if…else…语句的执行特点是二选一,在多个if…else…语句中,如果某个条件成立,则后续就不再继续判断了。
代码语言:javascript复制//小练习
var height = parseFloat(prompt('请输入身高(m):'));
var weight = parseFloat(prompt('请输入体重(kg):'));
var bmi = weight / (height * height);
if(bmi>32)
console.log('严重肥胖');
else if(bmi > 28 && bmi <=32)
console.log('肥胖');
else if(bmi > 25 && bmi <=28)
console.log('过重');
else if(bmi > 18.5 && bmi <=25)
console.log('正常');
else
console.log('过轻');
3、循环
JavaScript的循环有两种,一种是for循环,通过初始条件、结束条件和递增条件来循环执行语句块:
1、for循环
代码语言:javascript复制var x = 0;
var i;
for (i=1; i<=10000; i ) {
x = x i;
}
x; // 50005000
for循环最常用的地方是利用索引来遍历数组:
代码语言:javascript复制var arr = ['Apple', 'Google', 'Microsoft'];
var i, x;
for (i=0; i<arr.length; i ) {
x = arr[i];
console.log(x);
}
for循环的3个条件都是可以省略的,如果没有退出循环的判断条件,就必须使用break语句退出循环,否则就是死循环。用法与其他语言类似。
2、for… in
for循环的一个变体是for … in循环,它可以把一个对象的所有属性依次循环出来:
代码语言:javascript复制var o = {
name: 'Jack',
age: 20,
city: 'Beijing'
};
for (var key in o) {
console.log(key); // 'name', 'age', 'city'
}
注意,要过滤掉对象继承的属性,使用hasOwnProperty()来实现:
代码语言:javascript复制var o = {
name: 'Jack',
age: 20,
city: 'Beijing'
};
for (var key in o) {
if (o.hasOwnProperty(key)) {
console.log(key); // 'name', 'age', 'city'
}
}
Array也是对象,而它的每个元素的索引被视为对象的属性,for … in循环可以直接循环出Array的索引:
代码语言:javascript复制var a = ['A', 'B', 'C'];
for (var i in a) {
console.log(i); // '0', '1', '2'
console.log(a[i]); // 'A', 'B', 'C'
}
请注意,for … in对Array的循环得到的是String而不是Number
3、while
while循环只有一个判断条件,条件满足,就不断循环,条件不满足时则退出循环。比如我们要计算100以内所有奇数之和,可以用while循环实现:
代码语言:javascript复制var x = 0;
var n = 1;
while (n < 100) {
x = x n;
n = n 2;
}
x; // 2500
do - while
do { … } while()循环,它和while循环的唯一区别在于,不是在每次循环开始的时候判断条件,而是在每次循环完成的时候判断条件:
代码语言:javascript复制do {
n = n 1;
} while (n < 100);
n; // 100
do { … } while()循环体会至少执行1次,而for和while循环则可能一次都不执行。
4、Map和Set
1、Map
JavaScript的默认对象表示方式{}可以视为其他语言中的Map或Dictionary的数据结构,即一组键值对。 但是JavaScript的对象有个小问题,就是键必须是字符串。但实际上Number或者其他数据类型作为键也是非常合理的。 为了解决这个问题,最新的ES6规范引入了新的数据类型Map。 用JavaScript写一个Map如下:
代码语言:javascript复制var m = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]);
m.get('Michael'); // 95
初始化Map需要一个二维数组,或者直接初始化一个空Map。Map具有以下方法:
代码语言:javascript复制var m = new Map(); // 空Map
m.set('Adam', 67); // 添加新的key-value
m.set('Bob', 59);
m.has('Adam'); // 是否存在key 'Adam': true
m.get('Adam'); // 67
m.delete('Adam'); // 删除key 'Adam'
m.get('Adam'); // undefined
由于一个key只能对应一个value,所以,多次对一个key放入value,后面的值会把前面的值冲掉:
代码语言:javascript复制var m = new Map();
m.set('Adam', 67);
m.set('Adam', 88);
m.get('Adam'); // 88
2、Set
Set和Map类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在Set中,没有重复的key。 要创建一个Set,需要提供一个Array作为输入,或者直接创建一个空Set:
代码语言:javascript复制var s1 = new Set(); // 空Set
var s2 = new Set([1, 2, 3]); // 含1, 2, 3
重复元素在Set中自动被过滤:
代码语言:javascript复制var s = new Set([1, 2, 3, 3, '3']);
s; // Set {1, 2, 3, "3"}
通过add(key)方法可以添加元素到Set中,可以重复添加,但不会有效果:
代码语言:javascript复制s.add(4);
s; // Set {1, 2, 3, 4}
s.add(4);
s; // 仍然是 Set {1, 2, 3, 4}
通过delete(key)方法可以删除元素:
代码语言:javascript复制var s = new Set([1, 2, 3]);
s; // Set {1, 2, 3}
s.delete(3);
s; // Set {1, 2}
- set使用示例
let mySet = new Set();
mySet.add(1); // Set [ 1 ]
mySet.add(5); // Set [ 1, 5 ]
mySet.add(5); // Set [ 1, 5 ]
mySet.add("some text"); // Set [ 1, 5, "some text" ]
let o = {a: 1, b: 2};
mySet.add(o);
mySet.add({a: 1, b: 2}); // o 指向的是不同的对象,所以没问题
mySet.has(1); // true
mySet.has(3); // false
mySet.has(5); // true
mySet.has(Math.sqrt(25)); // true
mySet.has("Some Text".toLowerCase()); // true
mySet.has(o); // true
mySet.size; // 5
mySet.delete(5); // true,从 set 中移除 5
mySet.has(5); // false, 5 已经被移除
mySet.size; // 4,刚刚移除一个值
console.log(mySet);
// logs Set(4) [ 1, "some text", {…}, {…} ] in Firefox
// logs Set(4) { 1, "some text", {…}, {…} } in Chrome
- 迭代set
// 迭代整个 set
// 按顺序输出:1, "some text", {"a": 1, "b": 2}, {"a": 1, "b": 2}
for (let item of mySet) console.log(item);
// 按顺序输出:1, "some text", {"a": 1, "b": 2}, {"a": 1, "b": 2}
for (let item of mySet.keys()) console.log(item);
// 按顺序输出:1, "some text", {"a": 1, "b": 2}, {"a": 1, "b": 2}
for (let item of mySet.values()) console.log(item);
// 按顺序输出:1, "some text", {"a": 1, "b": 2}, {"a": 1, "b": 2}
//(键与值相等)
for (let [key, value] of mySet.entries()) console.log(key);
// 使用 Array.from 转换 Set 为 Array
var myArr = Array.from(mySet); // [1, "some text", {"a": 1, "b": 2}, {"a": 1, "b": 2}]
// 如果在 HTML 文档中工作,也可以:
mySet.add(document.body);
mySet.has(document.querySelector("body")); // true
// Set 和 Array 互换
mySet2 = new Set([1, 2, 3, 4]);
mySet2.size; // 4
[...mySet2]; // [1,2,3,4]
// 可以通过如下代码模拟求交集
let intersection = new Set([...set1].filter(x => set2.has(x)));
// 可以通过如下代码模拟求差集
let difference = new Set([...set1].filter(x => !set2.has(x)));
// 用 forEach 迭代
mySet.forEach(function(value) {
console.log(value);
});
// 1
// 2
// 3
// 4
5、Iterable
- 遍历Array可以采用下标循环,遍历Map和Set就无法使用下标。为了统一集合类型,ES6标准引入了新的iterable类型,Array、Map和Set都属于iterable类型。
- 具有iterable类型的集合可以通过新的for … of循环来遍历。
- 用for … of循环遍历集合,用法如下:
var a = ['A', 'B', 'C'];
var s = new Set(['A', 'B', 'C']);
var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
for (var x of a) { // 遍历Array
console.log(x);
}
for (var x of s) { // 遍历Set
console.log(x);
}
for (var x of m) { // 遍历Map
console.log(x[0] '=' x[1]);
}
- for-in与for-of的区别 观察下面代码的不同。
var a = ['A', 'B', 'C'];
a.name = 'Hello';
for (var x in a) {
console.log(x); // '0', '1', '2', 'name'
}
for … in循环将把name包括在内,但Array的length属性却不包括在内。 for … of循环则完全修复了这些问题,它只循环集合本身的元素:
代码语言:javascript复制var a = ['A', 'B', 'C'];
a.name = 'Hello';
for (var x of a) {
console.log(x); // 'A', 'B', 'C'
}
- 更好的方式是直接使用iterable内置的forEach方法,它接收一个函数,每次迭代就自动回调该函数。以Array为例:
var a = ['A', 'B', 'C'];
a.forEach(function (element, index, array) {
// element: 指向当前元素的值
// index: 指向当前索引
// array: 指向Array对象本身
console.log(element ', index = ' index);
});
Set与Array类似,但Set没有索引,因此回调函数的前两个参数都是元素本身
代码语言:javascript复制var s = new Set(['A', 'B', 'C']);
s.forEach(function (element, sameElement, set) {
console.log(element);
});
Map的回调函数参数依次为value、key和map本身:
代码语言:javascript复制var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
m.forEach(function (value, key, map) {
console.log(value);
});
如果对某些参数不感兴趣,由于JavaScript的函数调用不要求参数必须一致,因此可以忽略它们。例如,只需要获得Array的element:
代码语言:javascript复制var a = ['A', 'B', 'C'];
a.forEach(function (element) {
console.log(element);
});