大家好!我是方才,目前是8人后端研发团队的负责人,拥有6年后端经验&3年团队管理经验,截止目前面试过近200位候选人,主导过单表上10亿、累计上100亿数据量级的业务系统的架构和核心编码。 “学编程,一定要系统化” 是我一直坚持的学习之道。目前正在系统化分享从零到一的全栈编程入门以及项目实战教程。 无论你是编程新手,还是有经验的开发者,我都愿意与你分享我的学习方法、项目实战经验,甚至提供学习路线制定、简历优化、面试技巧等深度交流服务。 我创建了一个编程学习交流群(扫码关注后即可加入),秉持“一群人可以走得更远”的理念,期待与你一起 From Zero To Hero! 茫茫人海,遇见即是缘分!希望这篇文章对你有所帮助!
学习JavaScript
相对于html
和css
会复杂一点,js是一门正式的编程语言,和后续要学习的java
语言有一些共性,学习JavaScript
需要去理解变量、数据类型、函数。
JavaScript 是一种解释型编程语言,主要用于网页开发。它最初用于增强网页交互性,如响应用户点击、更新内容等。现在,JavaScript 已经扩展到了服务端(通过 Node.js),以及移动应用等多个领域。
JavaScript 的用途:
JavaScript 与 HTML/CSS 的关系:
JavaScript 的运行环境:
ECMAScript是一种语言标准,简称 ES。JavaScript 是基于该标准的一种实现。
ES6(也称为 ECMAScript 2015)是 JavaScript 的一个重大更新,加入了许多新特性,如 let
和 const
、箭头函数、模板字符串、模块等。
大小写敏感:变量名区分大小写。
let Name = "John";
let name = "Doe"; // 这是不同的两个变量
代码块:使用 {}
来定义代码块。
if (true) {
console.log("代码块执行");
}
分号:每个语句通常以分号结尾,尽管在某些情况下 JavaScript 会自动插入分号,但明确加上分号是个好习惯。
let a = 5;
let b = 10;
console.log(a + b);
注释用于为代码提供说明,不会执行。
单行注释:使用 //
。
// 这是一个单行注释
let a = 5; // 也可以写在代码的旁边
多行注释:使用 /* */
。
/*
这是一个多行注释
它可以跨越多行
*/
let b = 10;
console.log()
console.log()
用于在浏览器的控制台打印输出,是调试 JavaScript 代码的重要工具。
console.log("Hello, World!"); // 控制台输出 "Hello, World!"
我们可以直接在 Chrome 浏览器中创建一个脚本来执行:
F12
快捷键打开:let person = {
name: "方才coding",
age: 30,
isStudent: false
};
console.log(person.name); // 输出 "方才coding"
保存后,右击文件名,选择 "Run" 执行代码:
JavaScript 中有多种数据类型,用于存储不同种类的信息。
什么是变量?这里直接引用ChatGPT
的回答:
变量就像一个小盒子,你可以把信息(比如数字、文字、或者其他东西)放进去,然后给这个盒子起个名字。以后,当你想要用这个信息时,只需要叫这个名字就能找到它。
比如,如果你有一个数字 `10`,你可以把它放到一个叫 `age` 的盒子里。以后你只要叫 `age`,就能知道盒子里的数字是 `10`。在编程里,这个盒子就叫变量。
**var
**:旧版声明方式,允许变量提升(变量可以在声明之前使用,导致不可预期的错误)。
var x = 5;
**let
**:块级作用域,避免变量提升问题。
let y = 10;
**const
**:声明常量,值一旦赋值后不可修改。
const z = 20;
// z = 30; // 会抛出错误
字符串(String):表示文本。
let name = "Alice"; // 使用双引号
let greeting = 'Hello'; // 使用单引号
数字(Number):可以是整数或浮点数。
let age = 30;
let pi = 3.14;
布尔值(Boolean):true
或 false
,用于逻辑判断。
let isStudent = true;
let isGraduated = false;
空值(Null):表示一个空或不存在的值。
let emptyValue = null;
未定义(Undefined):声明了变量但未赋值。
let notAssigned;
console.log(notAssigned); // 输出 undefined
Symbol 和 BigInt(ES6+):特殊类型,用于唯一标识符和大整数。
Symbol:ES6 中新增的类型,用来创建唯一的标识符。即使两个 Symbol 的值相同,它们依然是独一无二的。例如:
javascript复制代码let symbol1 = Symbol('description');
let symbol2 = Symbol('description');
console.log(symbol1 === symbol2); // false
对象(Object):用于存储键值对。
let person = {
name: "方才coding",
age: 18,
isStudent: false
};
console.log(person.name); // 输出 "方才coding"
数组(Array):有序的元素集合,可以存储多个值,通过下标 index 访问,下标值从0开始。
let fruits = [1,2,3,3];
console.log(fruits[0]); // 输出 "1"
Map: ES6 引入的集合类型,是一种键值对的集合,其中的键可以是任何类型的数据。例如:
let map = new Map();
map.set('name', '方才coding');
map.set('age', 18);
console.log(map.get('name')) // 输出 "方才coding"
Set:ES6 引入的集合类型,是一种集合,它只存储唯一的值,没有重复项。例如:
let set = new Set([1, 2,3, 3]);
console.log(set); // 输出 Set { 1, 2, 3 }
正则表达式(RegExp):是一种匹配模式,用于匹配字符串中的字符组合。例如:
let pattern = /hello/;
let result = pattern.test("hello world");
console.log(result); // true
日期(Date):Date
对象用于处理日期和时间。例如:
let now = new Date(); // 获取当前日期和时间
console.log(now); //Thu Oct 10 2024 22:30:09 GMT+0800 (中国标准时间)
函数(Function):函数也是对象的一种,在 JavaScript 中,函数是可以赋值给变量、作为参数传递的“第一类公民”。
function greet() {
console.log("Hello, world!");
}
在JavaScript中,值类型和引用类型就像是两种不同的“储存方式”。
值类型:
值类型就像你把东西(比如一个数字)写在纸上,每次你想要它的时候,都会得到一个副本。如果你改了这个副本,原来的数字不会变。也就是说,每次使用的时候你拿到的是一份独立的拷贝。
例子:你有个数字 10
,如果把这个 10
赋值给另一个变量,两个数字之间没有关系。如果你改了一个,另一个不会变。
let x = 10; // x 是一个值类型
let y = x; // y 得到的是 x 的副本(拷贝)
console.log("原来的x=",x); // 输出 10
console.log("原来的y=",y); // 输出 10
y = 20; // 改变 y,不会影响 x
console.log("新的x=",x); // 输出 10,x 没有改变
console.log("新的y=",y); // 输出 20,y 已经被修改
原来的x= 10
原来的y= 10
新的x= 10
新的y= 20
图例:
引用类型:
引用类型就像把东西放在一个大箱子里,然后把这个箱子的钥匙(地址)给你。每次你想要用里面的东西,都是用这把钥匙去打开同一个箱子。如果有人用这把钥匙去改了箱子里的东西,所有有这把钥匙的人看到的内容都会变,因为大家用的是同一个箱子。
例子:你有一个装着数字的箱子,如果你把箱子的钥匙给别人,别人讲里面的东西变了,大家看到的都会变。
let obj1 = { x: 10 }; // obj1 是一个引用类型(对象)
let obj2 = obj1; // obj2 得到了 obj1 的引用(钥匙)
obj2.x = 20; // 改变 obj2 里面的内容
console.log(obj1.x); // 输出 '20',因为 obj1 和 obj2 引用的是同一个对象
console.log(obj2.x); // 输出 '20',obj2 被修改后,obj1 也跟着变了
这里要注意,如果你直接更换了变量的地址(把箱子的钥匙给换了),那这个变量后续的内容变更是不影响之前的变量的:
let obj1 = { x: 10 }; // obj1 是一个引用类型(对象)
let obj2 = obj1; // obj2 得到了 obj1 的引用(钥匙)
obj2 = { x: 10 }; // 这里改变 obj2 的引用值(一个新的箱子钥匙)
obj2.x = 20; // 改变 obj2 里面的内容
console.log(obj1.x); // 输出 '10',因为 obj1 没有被更改
console.log(obj2.x); // 输出 '20',obj2 已经换了一个新的引用,变更只影响新的箱子
总结:
typeof
是一个 JavaScript 关键字,用于判断一个变量或值的数据类型。它可以返回以下几种结果:
"string"
:字符串类型"number"
:数字类型"boolean"
:布尔类型"undefined"
:未定义类型"object"
:对象类型(包括 null
)"function"
:函数类型"symbol"
:符号类型console.log(typeof "Hello"); // 输出 "string"
console.log(typeof 42); // 输出 "number"
console.log(typeof true); // 输出 "boolean"
console.log(typeof undefined); // 输出 "undefined"
console.log(typeof null); // 输出 "object" (注意,`null` 的类型是对象,这是 JavaScript 的历史遗留问题)
console.log(typeof { name: "方才coding" }); // 输出 "object"
console.log(typeof function(){}); // 输出 "function"
console.log(typeof Symbol("id")); // 输出 "symbol"
JavaScript 中的 Array
、Map
和 Set
是常用的数据结构,它们提供了丰富的方法来操作数据。以下是对它们的详细介绍:
数组是一种可以存储多个值的对象。它的索引从 0
开始,可以存储不同类型的数据。
**push()
**:向数组末尾添加一个或多个元素,返回新数组的长度。
let arr = [1, 2];
arr.push(3); // arr: [1, 2, 3]
**pop()
**:删除数组的最后一个元素,返回该元素。
let arr = [1, 2, 3];
let lastElement = arr.pop(); // arr: [1, 2], lastElement: 3
**shift()
**:删除数组的第一个元素,返回该元素。
let arr = [1, 2, 3];
let firstElement = arr.shift(); // arr: [2, 3], firstElement: 1
**unshift()
**:向数组开头添加一个或多个元素,返回新数组的长度。
let arr = [2, 3];
arr.unshift(1); // arr: [1, 2, 3]
**forEach()
**:对数组的每个元素执行一次提供的函数。
let arr = [1, 2, 3];
arr.forEach((item) => console.log(item)); // 输出 1 2 3
**map()
**:对数组的每个元素执行一次提供的函数,返回一个新数组。
let arr = [1, 2, 3];
let squared = arr.map((item) => item * item); // squared: [1, 4, 9]
**filter()
**:返回符合条件的元素的新数组。
let arr = [1, 2, 3, 4];
let evenNumbers = arr.filter((item) => item % 2 === 0); // evenNumbers: [2, 4]
**reduce()
**:将数组元素通过累积方式计算为一个值。
let arr = [1, 2, 3, 4];
let sum = arr.reduce((acc, item) => acc + item, 0); // sum: 10
**find()
**:返回第一个满足条件的元素。
let arr = [1, 2, 3, 4];
let found = arr.find((item) => item > 2); // found: 3
**findIndex()
**:返回第一个满足条件的元素的索引。
let arr = [1, 2, 3, 4];
let index = arr.findIndex((item) => item > 2); // index: 2
**includes()
**:判断数组是否包含某个值。
let arr = [1, 2, 3];
let hasTwo = arr.includes(2); // hasTwo: true
**slice()
**:返回数组的一个子数组,不修改原数组。
let arr = [1, 2, 3, 4];
let subArray = arr.slice(1, 3); // subArray: [2, 3]
**splice()
**:删除或替换现有元素,或添加新元素,修改原数组。
let arr = [1, 2, 3, 4];
let removed = arr.splice(1, 2); // removed: [2, 3], arr: [1, 4]
Map
是一种存储键值对的集合,其中的键可以是任意类型。
**set()
**:添加或更新键值对。
let map = new Map();
map.set('name', 'Alice'); // map: { 'name' => 'Alice' }
**get()
**:根据键获取对应的值。
let name = map.get('name'); // name: 'Alice'
**has()
**:判断 Map 是否包含指定键。
let hasName = map.has('name'); // hasName: true
**delete()
**:删除指定键的键值对。
map.delete('name'); // map: {}
**clear()
**:清空 Map 中的所有键值对。
map.clear(); // map: {}
**size
**:返回 Map 中键值对的数量。
let map = new Map();
map.set('name', 'Alice');
let size = map.size; // size: 1
**keys()
**:返回包含 Map 所有键的迭代器。
for (let key of map.keys()) {
console.log(key); // 'name'
}
**values()
**:返回包含 Map 所有值的迭代器。
for (let value of map.values()) {
console.log(value); // 'Alice'
}
**entries()
**:返回包含 Map 所有键值对的迭代器。
for (let entry of map.entries()) {
console.log(entry); // ['name', 'Alice']
}
**forEach()
**:对 Map 中的每一个键值对执行一次回调函数。
map.forEach((value, key) => {
console.log(key, value); // 'name' 'Alice'
});
Set
是一种存储唯一值的数据结构,重复的值会被自动去重。
**add()
**:向 Set 添加一个元素。
let set = new Set();
set.add(1); // set: {1}
**has()
**:判断 Set 是否包含某个值。
let hasOne = set.has(1); // hasOne: true
**delete()
**:删除 Set 中的某个元素。
set.delete(1); // set: {}
**clear()
**:清空 Set 中的所有元素。
set.clear(); // set: {}
**size
**:返回 Set 中元素的数量。
let set = new Set([1, 2, 3]);
let size = set.size; // size: 3
**forEach()
**:对 Set 中的每一个元素执行一次回调函数。
set.forEach((value) => {
console.log(value); // 1, 2, 3
});
**values()
**:返回包含 Set 所有值的迭代器(Set 没有键)。
for (let value of set.values()) {
console.log(value); // 1, 2, 3
}
**entries()
**:返回包含 Set 所有键值对的迭代器(键和值是同一个元素)。
for (let entry of set.entries()) {
console.log(entry); // [1, 1], [2, 2], [3, 3]
}
+
:加法-
:减法*
:乘法/
:除法%
:取余let a = 10;
let b = 3;
console.log(a + b); // 输出 13
console.log(a - b); // 输出 7
console.log(a * b); // 输出 30
console.log(a / b); // 输出 3.33333...
console.log(a % b); // 输出 1
==
和 ===
:相等运算符,===
是严格相等,要求类型也相同。!=
和 !==
:不等运算符,!==
是严格不等。<
、>
、<=
、>=
:大小比较。console.log(5 == '5'); // 输出 true
console.log(5 === '5'); // 输出 false(类型不同)
&&
:与(AND)||
:或(OR)!
:非(NOT)let isAdult = true;
let hasPermission = false;
console.log(isAdult && hasPermission); // 输出 false
console.log(isAdult || hasPermission); // 输出 true
console.log(!isAdult); // 输出 false
近期更新计划(有需要的小伙伴,记得点赞关注哟!)
“学编程,一定要系统化”——若你也是系统学习的践行者,记得点赞关注,期待与你一起 From Zero To Hero!