现代编程语言中,最基本的数据格式都会是字符串和数字。字符串用于表达人类文明的自然语言,数字用于表达量化世界的各种数值。

一、字符串

字符串的运用包括,字符串的创建、分割、大小写转换、拼接等

1-1 创建字符串

在 JavaScript 中创建一个字符串跟其他语言并没有较大的区别,可以分别使用 ‘、” 和 ` 作为边界标识。

1
2
3
const str1 = "string 1";
const str2 = "string 2";
const str3 = `string 3`;

从 JavaScript 的语法定义上 ‘ 和 “ 并没有太大的差别,但是 ` 的用途较为特殊。 同样可以以与 ‘ 和 “ 一样的使用方式使用,但也可以有更高级的用法。

例如:

1
2
const target = "world";
const word = `hello ${target}`; // => hello world

同时 ` 也可以用于创建一个“多行字符串”,即字符串内容中包含多行文本。

1-2 分割字符串

例如:如何将 “Hey jude,how is it going?” 转换为“hey jude how is it going”

二者不同之处在于,去除了文本中的标点符号、数字、大写字母转换为小写字母。

任务理解:去除标点符号、数字可以说是只保留英文字母,只需筛选出英文字母和空格即可,需要使用 ASCII 码进行甄别,大写字母的 ASCII 码范围为 65 到 90(即:A-Z),小写字母则为 97 到 122,空格的 ASCII 码为 32,换行符的 ASCII 码为 10。JS 中可以用 string.charCodeAt()方法获取字符串的 ASCII 码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const originalText = "Hey jude,how is it going?";
let wordOnlyText = "";
for (let i = 0; i < originalText.length; i++) {
const letter = originalText[i];
const asciiCode = letter.charCodeAt();
if (
(asciiCode >= 65 && asciiCode <= 90) ||
(asciiCode >= 97 && asciiCode <= 122) ||
asciiCode === 32
) {
wordOnlyText += letter;
}
}

console.log(wordOnlyText); // => Hey judehow is it going

将大写字母转换为小写字母

string.charCodeAt() 方法来获取字符的 ASCII 码,那么自然也有对应的方法用于将 ASCII 码转换为对应字符 String.fromCharCode(code)。

而从字母的 ASCII 码范围可以看到,将大写字母的 ASCII 码数值加上 32 便是其对应小写字母的 ASCII 码数值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
let lowerCaseText = "";

for (let i = 0; i < wordOnlyText.length; ++i) {
const letter = wordOnlyText[i];
const asciiCode = letter.charCodeAt();

if (asciiCode >= 65 && asciiCode <= 90) {
lowerCaseText += String.fromCharCode(asciiCode + 32);
} else {
lowerCaseText += letter;
}
}

console.log(lowerCaseText); // => hey judehow is it going

在 JavaScript 中早就已经内置了将文本中的大写字母转换为小写字母的 API 了 —— string.toLowerCase()。

1
const lowerCaseText = wordOnlyText.toLowerCase();

1-3 字符串的分割

最主要用到的方法便是 string.split(separator),其中这个 separator 则是定义了用于分割字符串内容的“分割符”。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
const originalText = `
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
`;

let wordOnlyText = "";

for (let i = 0; i < originalText.length; ++i) {
const letter = originalText[i];
const asciiCode = letter.charCodeAt();

if (
(asciiCode >= 65 && asciiCode <= 90) ||
(asciiCode >= 97 && asciiCode <= 122) ||
asciiCode === 32
) {
wordOnlyText += letter;
}
}

const lowerCaseText = wordOnlyText.toLowerCase();

const words = lowerCaseText.split(" ");

console.log(words.length); //=> 160

1-4 字符串的拼接

除了对字符串进行拆分以外,我们也常常需要将不同的信息通过各种方式拼装成一个完整的字符串信息。最常见的例子便是我们几乎每天都能遇见的,由程序自动发送的自动短信、自动邮件等。

字符串之间的连接可以直接使用 + 运算符完成。

1
2
3
const str1 = "hello";
const str2 = "world";
console.log(str1 + " " + str2); // => 'hello world'

使用 + 运算符是最基本的字符串拼接方式,适用于数据量较小的字符串拼接。数据量大时,我们需要将多个数据量‘嵌入’到文本模板中,这种情况通常可以使用模板引擎来实现这个功能。

1
2
3
4
5
6
7
8
9
10
const name = "jude";
const level = "Gold";

const message = `
Hello,${name}.
Here is LOL account,you are the ${level} of our games.
`;
console.log(message);
// => Hello,jude.
// Here is LOL account,you are the Gold of our games.

loading…

二、对象字面量

2-1 对象的内容读取

JavaScript 中对象内容读取十分的简单,如果属性键为字符串,且该字符串中只包含英文字母和下划线的话,可以直接用 . 来读取属性值。

1
2
3
4
5
6
7
8
9
10
11
12
13
const person = {
name: "jude",
age: "18",
skills: {
title: "vue",
desc: "mvvm",
author: "Evan You",
},
others: "....",
};

console.log(person.name); // => jude
console.log(person.skills.title); // => vue

而当对象中所需要读取的目标属性键为数字、包含英文字母和下划线以外的字符串甚至是 Symbol 对象的时候,就需要使用 obj[key] 的形式来读取属性值了。

1
2
3
4
5
6
7
8
const obj = {
1: 2,
"a b c": "d e f",
[Symbol.for("foo")]: "bar",
};
console.log(obj[1]); // => 2
console.log(obj["a b c"]); // => d e f
console.log(obj[Symbol.for("foo")]); // => bar

2-2 修改对象内容

const 语句定义的对象是不能直接被替换,但是其中的内容依然是能被修改的。
在 JavaScript 中存在着“引用”和“值”的概念区别,对对象内容进行修改跟进行读取类似,只是在读取语句后面加上 = 即可。

1
2
3
4
5
6
7
8
9
10
const obj = {
foo: "bar",
1: 2,
"a b c": "d e f",
[Symbol.for("foo")]: "bar",
};
obj.foo = "read";
obj[1] = 3;
console.log(obj.foo); // => read
console.log(obj[1]); // => 3

当你需要为一个对象添加新的属性时,也是通过同样的方式添加属性。

1
2
3
const obj = {};
obj.foo = "bar";
obj[1] = 2;

在一般情况下,无论是对对象进行添加、读取还是修改属性,都遵循着嵌套链完整的原则

1
2
3
4
5
const outer = {
inner: {},
};
outer.inner.foo = "bar"; // success
outer.something.bar = 1; // error

三、数组

3-1 数组增加内容

向数组内增加内容包括向数组首端、末尾、中间添加新内容

添加到末端:array.push()

1
2
3
4
5
6
7
const array = [];
array.push(1);
console.log(array); // => [1]

array.push(2, 3);
console.log(array); // => [1,2,3]
console.log(array.length); // 3

添加到首端: array.unshift()

1
2
3
4
5
6
const array = [4, 5];
array.unshift(3);
console.log(array); // => [3,4,5]

array.unshift(1, 2);
console.log(array); // => [1,2,3,4,5]

添加到数组中间某一位置:array.splice(start,deleteCount,element,….)

该方法第二个参数是 deleteCount,因为这个方法也可以用来删除数组中某一个位置开始的若干个元素,而当我们将这个参数设置为 0 的时候,该方法第三个以及后面的参数便会插入到下标为 start 的位置,后面的元素自动往后推导。

1
2
3
4
5
6
const array = [1, 2, 6, 7];
array.splice(2, 0, 3);
console.log(array); // => [1,2,3,6,7]

array.splice(3, 0, 4, 5);
console.log(array); // => [1,2,3,4,5,6,7]

查找内容:filter

filter 过滤器的逻辑便是定义一个过滤函数,该函数会有序地被传入数组中当前下标的元素,而它则需要返回该函数是否符合其过滤要求,即结果为 true 或 false。

1
2
3
4
5
6
const array = [1, 2, 3, 4, 5, 6, 7, 8];
const evenNumbers = array.filter(function (x) {
return x % 2 == 0;
});

console.log(evenNumbers); // => [2,4,6,8]

删除内容:array.splice(start,deleteCount)

1
2
3
const array = [1, 2, 3, 10, 4, 5];
array.splice(3, 1);
console.log(array); // => [1,2,3,4,5]

更新内容

1
2
3
const array = [1, 2, 3, 4, 5];
array[0] = 10;
console.log(array); // => [10,2,3,4,5]

封装数组操作工具

虽然绝大多数操作都可以直接使用 JavaScript 中自带的 API 来实现,但是如 array.splice() 这种方法看上去就很容易产生操作错误。那么为了避免开发中的失误,我们可以通过定义一个抽象对象来封装一个用于操作数组的工具库。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
const arrayUtils = {
// 末端添加
append(array,...elements){
array.push(...elements)
return array
},
// 首端添加
prepend(array,...elements){
array.unshift(...elements)
return array
}
// 中间插入
insert(array,index,...elements){
array.splice(index,0,...elements)
return array
}
// 删除内容
remove(array,index){
array.splice(index,1)
return array
}
}
// 使用
const array = []
arrayUtils.append(array,3)
arrayUtils.prepend(array,1)
arrayUtils.insert(array,1,2)
console.log(array) // => [1,2,3]

arrayUtils.remove(array,1)
console.log(array) // => [1,3]

3-2 数组转换/聚合

map

1
2
3
4
5
6
const array = [1, 2, 3, 4, 5];
const addedArray = array.map(function (x) {
return x + 2;
});

console.log(addedArray); // => [3,4,5,6,7]

reduce

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
const array = [1,2,3,4]
const sumResult = array.reduce(function(a,b){
return a + b
})
console.log(sumResult) // => 10

function multi(array){
return array.reduce(function(a,b){
return a * b
})
}
console.log(multi(array))

// 函数式编程,进一步抽象封装
const array = [1,2,3,4]
function reduceFn(callback){
return funtion(array){
return array.reduce(callback)
}
}

const sum = reduceFn(function(a,b){
return a + b
})
const multi = reduceFn(function(a,b){
return a + b
})
console.log(sum(array)) // => 10
console.log(multi(array)) // => 24

1、将数组[1,2,3,4,5] 转换为 [‘a1’,’a2’,’a3’,’a4’,’a5’]

1
2
3
4
const array = [1, 2, 3, 4, 5];
const result = array.map((item) => {
return "a" + item;
});

将数组 [ 1, 2, 3, 4, 5 ] 转换为 [ ‘a1’, ‘b2’, ‘c3’, ‘d4’, ‘e5’ ]

1
2
3
4
5
const array = [1, 2, 3, 4, 5];
const result = array.map((item) => {
return String.fromCharCode(96 + item) + item;
});
console.log(result);

将数组 [ 1, 2, 3, 4, 5 ] 转换为 [ 1, 4, 9, 16, 25 ]

1
2
3
4
5
const array = [1, 2, 3, 4, 5];
const result = array.map((item) => {
return Math.pow(item, 2);
});
console.log(result);

查询 JavaScript 中 Array.prototype.map 方法的详细文档,并将数组 [ 0, 0, 0, 0, 0 ] 转换为 [ ‘A’, ‘B’, ‘C’, ‘D’, ‘E’ ]

1
2
3
4
5
const array = [0, 0, 0, 0, 0];
const result = array.map((item, index) => {
return String.fromCharCode(65 + index);
});
console.log(result);

提取数组 [ 1, 2, 3, 4, 5 ] 中的 [ 2, 3, 4 ]

1
2
3
4
5
const array = [1, 2, 3, 4, 5];
const result = array.filter((item) => {
return item > 1 && item < 5;
});
console.log(result);