原生 JavaScript(也称为 Vanilla JS)指的是不依赖于任何框架或库的纯 JavaScript。以下是原生 JavaScript 的一些基本内容和常用特性详解。
目录
一、数据类型
1.原始类型
2.引用类型
二、变量声明
1.相同点
2.不同点
3.示例
4.总结
三、控制结构
1. 条件语句
1.1 if 语句
1.2 else if 语句
1.3 switch 语句
2. 循环结构
2.1 for 循环
2.2 while 循环
2.3 do...while 循环
3. 跳转控制
3.1 break
3.2 continue
4. 综合示例
5.总结
四、 函数
五、对象和数组
六、事件处理
七、DOM 操作
八、Promise 和异步编程
1. 传统的异步编程
2. Promise 的引入
3. async/await
4. 总结
九、模块化
十、 JSON 操作
1. JSON 对象简介
2. JSON.parse()
3. JSON.stringify()
4. 处理 JSON 数据的注意事项
5. 实际应用
6.总结
十一、总结
一、数据类型
JavaScript 有七种基本数据类型:
1.原始类型
Number:数字类型,例如 42 或 3.14。String:字符串类型,例如 'Hello' 或 "World"。Boolean:布尔类型,只有两个值:true 或 false。Undefined:未定义的类型,表示变量未被赋值。Null:表示无值的类型,表示“空”。Symbol:ES6 引入的独特且不可变的数据类型,通常用于对象属性的标识。BigInt:用来表示大于 2^53 - 1 的整数。
默认初始值说明:
Number:
默认初始值为 0。let num; // num 的初始值为 undefined
num = num || 0; // 如果 num 是 undefined,则将其赋值为 0
String:
默认初始值为 ""(空字符串)。let str; // str 的初始值为 undefined
str = str || ""; // 如果 str 是 undefined,则将其赋值为 ""
Boolean:
默认初始值为 false。let flag; // flag 的初始值为 undefined
flag = flag || false; // 如果 flag 是 undefined,则将其赋值为 false
Undefined:
默认初始值为 undefined,表示变量声明但未赋值。let uninitialized; // uninitialized 的初始值为 undefined
Null:
可以显式设置初始值为 null,表示“空”或“无值”。let empty = null; // empty 的初始值为 null
Symbol:
需要显式定义,默认值为 undefined。如果要使用 Symbol,必须调用 Symbol()。let sym = Symbol(); // sym 的初始值为一个新的唯一 symbol
BigInt:
需要显式定义,默认值为 undefined。如果要使用 BigInt,必须通过 BigInt() 或在数字后加 n 来创建。let bigIntValue = BigInt(123); // BigInt 的初始值为 123n
2.引用类型
Object:对象类型,是键值对的集合。数组(Array):特殊的对象,用于存储有序的数据集合。函数(Function):也是对象,可以被调用。
默认值说明:
1. Object(对象)
默认值:对象没有“默认值”,但是如果声明一个对象而不赋值,它的初始值为 undefined。可以显式设置为空对象 {}。
let obj; // obj 的初始值为 undefined
obj = obj || {}; // 如果 obj 是 undefined,则将其赋值为 {}
2. Array(数组)
默认值:数组也没有“默认值”,如果声明一个数组而不赋值,它的初始值为 undefined。可以显式设置为空数组 []。
let arr; // arr 的初始值为 undefined
arr = arr || []; // 如果 arr 是 undefined,则将其赋值为 []
3. Function(函数)
默认值:函数的默认值同样是 undefined,如果声明一个函数而不赋值,可以显式设置为一个空函数或定义具体的函数体。
let myFunction; // myFunction 的初始值为 undefined
myFunction = myFunction || function() {}; // 如果 myFunction 是 undefined,则赋值为一个空函数
二、变量声明
var、let 和 const 是 JavaScript 中用于声明变量的三种关键字,它们在作用域、提升(Hoisting)、重赋值、初始化等方面各有不同,同时也有一些相同点。以下将详细介绍它们的相似性和区别:
1.相同点
用于声明变量:var、let 和 const 都可以用来定义变量,允许存储各种类型的数据,包括基本数据类型(如数字、字符串、布尔值)和引用数据类型(如对象、数组、函数等)。
影响变量的可用性:在同一作用域内声明的变量都是可用的,var、let 和 const 声明的变量都是在声明位置及以下可用。
都支持动态类型:声明的变量可以在不同时间赋值为不同类型的数据。
2.不同点
作用域:
var 具有函数作用域。这意味着在函数内部声明的变量仅在该函数内有效;如果在函数外部声明,则它是全局作用域的。let 和 const 具有块作用域。这意味着它们在最近的代码块(如 {} 中)中可用,无法在代码块外部访问。 提升(Hoisting):
var 声明的变量会被提升到其作用域的顶部,但在初始化之前,其值为 undefined。let 和 const 也会被提升,但在其声明之前,无法访问,因此会抛出 ReferenceError,这种状态称为“暂时性死区”(TDZ)。 重赋值与重声明:
使用 var 声明的变量可以被重新声明和重赋值。例如,可以在同一作用域中多次使用 var 声明同一变量。let 允许重赋值,但不允许重复声明同一变量。在同一作用域中只能使用一次 let。const 不仅不允许重赋值,还不允许重复声明。只有在声明时必须初始化,且不能在之后被重新赋值。需要注意的是,const 适用于对象和数组时,其内部的属性或元素仍然可以被修改,但变量本身的引用不能变化。 全局作用域和窗口对象:
在全局作用域中使用 var 声明的变量会成为 window 全局对象的属性。使用 let 或 const 声明的全局变量不会添加到 window 对象中,它们是全局作用域的属性,但不是 window 的属性。
3.示例
对于 var 的使用:
function testVar() {
var a = 1;
if (true) {
var a = 2; // 同一个作用域中的 a
console.log(a); // 输出 2
}
console.log(a); // 输出 2,var 具有函数作用域
}
testVar();
对于 let 的使用:
function testLet() {
let b = 1;
if (true) {
let b = 2; // 不同的作用域中的 b
console.log(b); // 输出 2
}
console.log(b); // 输出 1,let 具有块作用域
}
testLet();
对于 const 的使用:
const c = 5;
// c = 10; // TypeError: Assignment to constant variable
const obj = { name: "Alice" };
obj.name = "Bob"; // 可以修改对象的属性
console.log(obj.name); // 输出 Bob
4.总结
总的来说,var、let 和 const 在变量声明上都具有相同的基本功能,但它们在作用域、提升、重赋值和初始化等方面的不同特性使得它们适用于不同的场景。在现代 JavaScript 开发中,更推荐使用 let 和 const,因为它们提供了更清晰的代码结构和更好的代码可维护性。
三、控制结构
在原生 JavaScript 中,控制结构是影响程序执行流的语法,它们使得开发者能够根据不同的条件执行不同的代码块。以下是 JavaScript 中主要的控制结构的详细介绍。
1. 条件语句
1.1 if 语句
最基本的条件控制结构,根据布尔表达式决定是否执行某段代码。
if (condition) {
// 当 condition 为 true 时执行的代码
} else {
// 当 condition 为 false 时执行的代码(可选)
}
示例:
let age = 18;
if (age >= 18) {
console.log("成年人");
} else {
console.log("未成年人");
}
1.2 else if 语句
用于在 if 后添加多个条件判断。
if (condition1) {
// code
} else if (condition2) {
// code
} else {
// code (可选)
}
示例:
let score = 85;
if (score >= 90) {
console.log("优秀");
} else if (score >= 75) {
console.log("良好");
} else {
console.log("需要努力");
}
1.3 switch 语句
用于多个条件判断,根据给定的表达式的值,执行不同代码块。
switch (expression) {
case value1:
// code block
break;
case value2:
// code block
break;
default:
// code block (可选)
}
示例:
let fruit = "apple";
switch (fruit) {
case "banana":
console.log("这是香蕉");
break;
case "apple":
console.log("这是苹果");
break;
default:
console.log("未知水果");
}
2. 循环结构
2.1 for 循环
常用于已知次数的循环。
for (initialization; condition; increment) {
// code block
}
示例:
for (let i = 0; i < 5; i++) {
console.log(i); // 输出 0 1 2 3 4
}
2.2 while 循环
当条件为 true 时重复执行代码块,适用于不确定循环次数的情况。
while (condition) {
// code block
}
示例:
let count = 0;
while (count < 5) {
console.log(count); // 输出 0 1 2 3 4
count++;
}
2.3 do...while 循环
至少执行一次代码块,然后检查条件。
do {
// code block
} while (condition);
示例:
let num = 0;
do {
console.log(num); // 输出 0 1 2 3 4
num++;
} while (num < 5);
3. 跳转控制
3.1 break
用于提前结束循环或 switch 语句的执行。
for (let i = 0; i < 10; i++) {
if (i === 5) {
break; // 跳出循环
}
console.log(i);
}
3.2 continue
用于跳过当前循环的迭代,继续进行下一次迭代。
for (let i = 0; i < 10; i++) {
if (i % 2 === 0) {
continue; // 跳过偶数
}
console.log(i); // 输出奇数
}
4. 综合示例
结合所有控制结构,可以写出一个完整的示例:
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
for (let i = 0; i < numbers.length; i++) {
let num = numbers[i];
if (num % 2 === 0) {
console.log(num + " 是偶数");
} else {
console.log(num + " 是奇数");
}
}
5.总结
JavaScript 中的控制结构提供了丰富的条件和循环机制,使得开发者能够对程序的执行流程进行灵活的控制。掌握各种控制结构的用法是编写高效和清晰代码的基础。在实际开发中,合理使用这些控制结构可以使代码更加简洁和易于阅读。
四、 函数
JavaScript 中的函数也是一种对象,支持高阶函数(即可以接收函数作为参数的函数)。
声明函数:
function add(x, y) {
return x + y;
}
// 箭头函数
const sum = (x, y) => x + y;
五、对象和数组
对象的创建:
let person = {
name: 'Alice',
age: 25,
greet() {
console.log(`Hello, my name is ${this.name}`);
},
};
person.greet(); // Hello, my name is Alice
数组的创建和访问:
let fruits = ['apple', 'banana', 'cherry'];
console.log(fruits[0]); // apple
fruits.push('date'); // 添加元素
六、事件处理
使用原生 JavaScript 可以为 DOM 元素添加事件监听器。
let button = document.getElementById('myButton');
button.addEventListener('click', function() {
alert('Button clicked!');
});
七、DOM 操作
JavaScript 可以通过 document 对象操作 HTML 文档。
获取元素:
let element = document.querySelector('.myClass');
修改内容和样式:
element.textContent = 'New Content';
element.style.color = 'red';
创建和添加元素:
let newDiv = document.createElement('div');
newDiv.textContent = 'Hello, World!';
document.body.appendChild(newDiv);
八、Promise 和异步编程
Promise 和异步编程是 JavaScript 中用于处理异步操作的重要概念。理解这两者的工作原理和用法,可以有效提高代码的可读性和维护性。以下是对 Promise 及其与异步编程的关系的详细介绍。
1. 传统的异步编程
在 JavaScript 中,异步编程通常是通过回调函数来处理。回调函数是在某个异步操作完成后被调用的函数。这种方式称为回调模式,但它有一些缺点,比如“回调地狱”(Callback Hell),即当多个异步操作嵌套在一起时,代码的可读性和可维护性会降低。
function fetchData(callback) {
setTimeout(() => {
callback("数据获取成功");
}, 1000);
}
fetchData(function(result) {
console.log(result);
});
2. Promise 的引入
为了解决回调地狱的问题,JavaScript 引入了 Promise。Promise 是一个表示异步操作最终完成或失败的对象。它可以处于三种状态:
Pending(待定):初始状态,既不是成功也不是失败。Fulfilled(已兑现):操作成功完成。Rejected(已拒绝):操作失败。
2.1 Promise 的基本用法
Promise 通过 new Promise() 创建,并接收一个 executor 函数,该函数接受两个参数:resolve 和 reject,分别用于处理成功和失败。
const myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
const success = true; // 模拟操作结果
if (success) {
resolve("数据获取成功");
} else {
reject("数据获取失败");
}
}, 1000);
});
// 使用 Promise
myPromise
.then(result => {
console.log(result); // 输出: 数据获取成功
})
.catch(error => {
console.error(error);
});
2.2 Promise 链式调用
由于 then() 方法返回一个新的 Promise,因此可以进行链式调用,使得多个异步操作的顺序处理更加清晰。
myPromise
.then(result => {
console.log(result);
return "下一步操作";
})
.then(nextResult => {
console.log(nextResult); // 输出: 下一步操作
})
.catch(error => {
console.error(error);
});
3. async/await
随着 ES2017 的发布,JavaScript 引入了更简洁的异步编程语法——async/await。它基于 Promise,使得异步代码看起来更像同步代码,提高了可读性。
3.1 使用 async/await
async 关键字用于定义一个异步函数。在异步函数内部,可以使用 await 关键字等待 Promise 的结果。
async function fetchData() {
try {
const result = await myPromise; // 等待 Promise 完成
console.log(result); // 输出: 数据获取成功
} catch (error) {
console.error(error); // 捕获并处理错误
}
}
fetchData();
4. 总结
Promise 提供了一种更优雅的方式来处理异步操作,避免了回调地狱的出现,支持链式调用,增强了代码的可读性。async/await 更加简化了异步编程,使得处理异步操作的代码看起来更像同步代码,易于理解和维护。在使用 Promise 和 async/await 时,始终要注意错误处理,通过 catch() 和 try/catch 来捕获和处理错误。
九、模块化
使用 ES6 语法可以将代码模块化。
导出模块:
// myModule.js
export const name = 'Alice';
export function greet() {
console.log('Hello!');
}
导入模块:
// main.js
import { name, greet } from './myModule.js';
console.log(name); // Alice
greet(); // Hello!
十、 JSON 操作
在原生 JavaScript 中,JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人类阅读和编写,同时易于机器解析和生成。JavaScript 提供了内置的 JSON 对象,用于处理 JSON 数据。以下是对 JSON 操作的详细介绍,包括解析和字符串化等常见操作。
1. JSON 对象简介
JSON 对象包含两个主要的方法:
JSON.parse(): 将 JSON 字符串转换为 JavaScript 对象。JSON.stringify(): 将 JavaScript 对象转换为 JSON 字符串。
2. JSON.parse()
JSON.parse() 方法用于将 JSON 字符串解析转换为 JavaScript 对象。
语法:
JSON.parse(text[, reviver]);
text:要解析的 JSON 字符串。reviver(可选):一个函数,可以用来自定义转换的方式。
示例:
let jsonString = '{"name": "Alice", "age": 25, "isStudent": false}';
let jsonObject = JSON.parse(jsonString);
console.log(jsonObject.name); // 输出: Alice
console.log(jsonObject.age); // 输出: 25
console.log(jsonObject.isStudent); // 输出: false
使用 reviver 函数示例:
let jsonString = '{"name": "Alice", "age": 25}';
let jsonObject = JSON.parse(jsonString, (key, value) => {
if (key === 'age') {
return value + 1; // 将 age 加 1
}
return value;
});
console.log(jsonObject.age); // 输出: 26
3. JSON.stringify()
JSON.stringify() 方法用于将 JavaScript 对象转换为 JSON 字符串。
语法:
JSON.stringify(value[, replacer[, space]]);
value:要转换的 JavaScript 值(一般为对象或数组)。replacer(可选):一个函数或数组,可以用来选择性地包含哪些属性。space(可选):用来控制结果字符串的缩进。
示例:
let jsonObject = {
name: "Alice",
age: 25,
isStudent: false
};
let jsonString = JSON.stringify(jsonObject);
console.log(jsonString); // 输出: {"name":"Alice","age":25,"isStudent":false}
使用 replacer 函数示例:
let jsonObject = {
name: "Alice",
age: 25,
isStudent: false
};
let jsonString = JSON.stringify(jsonObject, (key, value) => {
if (typeof value === 'number') {
return value * 2; // 将数字属性的值乘以 2
}
return value;
});
console.log(jsonString); // 输出: {"name":"Alice","age":50,"isStudent":false}
使用 space 参数进行格式化示例:
let jsonObject = {
name: "Alice",
age: 25,
isStudent: false
};
let jsonString = JSON.stringify(jsonObject, null, 4); // 使用 4 个空格缩进
console.log(jsonString);
/*
输出:
{
"name": "Alice",
"age": 25,
"isStudent": false
}
*/
4. 处理 JSON 数据的注意事项
JSON 格式:JSON 必须使用双引号包裹字符串,属性名也必须使用双引号,例如:{"key": "value"}。不能使用单引号。不可序列化的值:一些值(如 undefined、函数和符号)不能被转换为 JSON。日期对象:Date 对象在转换为 JSON 时会被转换为字符串,解析时需要额外处理。
5. 实际应用
在实际应用中,JSON 通常用于与 API 进行交互。例如,在获取数据时,服务器发布 JSON 数据,客户端通过 fetch 请求获取后再使用 JSON.parse() 解析数据,或在将数据发送到服务器时用 JSON.stringify() 转换数据。
示例:获取 JSON 数据
fetch('https://api.example.com/data')
.then(response => response.json()) // 自动解析为 JSON 对象
.then(data => {
console.log(data); // 处理解析后的数据
})
.catch(error => console.error('请求错误:', error));
6.总结
JSON 是 JavaScript 操作数据的重要格式。通过 JSON.parse() 和 JSON.stringify() 方法,可以方便地在字符串和对象之间进行转换,从而便于数据的交换和存储。掌握这些基本操作是进行现代 Web 开发的基础。
十一、总结
原生 JavaScript 是构建 Web 应用的基础,能够处理 DOM 操作、事件监听、异步请求等核心功能。理解以上这些内容可以帮助你更好地使用和掌握 JavaScript,从而有效地进行 Web 开发。如果你想深入学习原生 JavaScript,可以参考 MDN 文档或其他相关教程。