变量和数据类型
数据类型
- 变量需要声明,使用var, let或const关键字。var声明的变量具有函数作用域,ES6新增的let和const具有块级作用域。
- JavaScript有6种简单数据类型(primitive types):number、string、boolean、null、undefined、symbol。还有一种复杂数据类型object。
- map不是一种数据类型,Symbol具有唯一性
- Map可以使用任意数据类型作为键,对象的键只能是字符串或符号。
- Map的键值是有序的,而对象的键值是无序的。
- Map的键值对个数可以直接得到,对象的键值对个数只能手动计算。
- Map是iterable的,可以直接用于迭代,对象的迭代需要先获取键数组。
- Map的键是唯一的,对象的键可能会重复。
- Symbol作为一种新的原始类型,具有唯一性和不可变性等特点,可以用于定义对象的唯一属性名,防止属性名冲突。
- map不是一种数据类型,Symbol具有唯一性
- number用于任意数字,包括整数和浮点数。string用于文本数据,可以用单引号或双引号表示。boolean只有true和false两个值。null表示空值。undefined表示未定义。symbol表示一个唯一标识。
- object用于更复杂的数据,可以包含多个不同的数据类型。常见的对象包括:数组、日期、正则表达式等。对象可以包含属性和方法。
- 声明变量时可以不初始化,会默认赋值为undefined。也可以在声明时对变量赋初始值,初始话为undefind时可以赋值为viod。
数据类型判断
- 使用typeof操作符判断基本数据类型:(null判断为Object)
js
const num = 1;
console.log(typeof num); // 'number'
- Object.prototype.toString方法可以准确判断对象的具体类型,不能判断基本数据类型:
js
const str = 'hello';
console.log(Object.prototype.toString.call(str)); // '[object String]'
- instanceof操作符,判断一个实例是否属于某个构造函数,存在改写的失误判断:
js
const arr = [];
console.log(arr instanceof Array); // true
- Array.isArray()方法,判断是否为数组:
js
console.log(Array.isArray(arr)); // true
5.利用每个类类型的特有属性,如 Array.isArray, String.prototype.charAt 等
数组、对象、Map、字符串处理的方法
数组
-
push() / pop() - 向数组末尾添加/删除项
-
unshift() / shift() - 向数组开头添加/删除项
-
concat() - 连接两个或更多数组,返回新数组
-
splice() - 删除/替换/插入项
-
slice() - 提取数组片段,返回新数组
-
indexOf() / lastIndexOf() - 查找项的索引
-
forEach() - 遍历数组
-
map() - 将数组中的每个元素映射到新数组
-
filter() - 过滤数组,返回符合条件的元素数组
-
reduce() - 将数组减少为单个值
-
sort() - 对数组排序
-
reverse() - 反转数组项顺序
-
join() - 将数组转换为字符串
-
isArray() - 判断是否为数组
-
fill() - 用静态值填充数组
-
flat() / flatMap() - 将多维数组扁平化
-
at() - 使用负索引访问数组项
-
find() / findIndex()- 查找符合条件的第一个元素/索引
-
every() / some() - 判断是否所有/部分元素满足条件
字符串
-
拼接:使用 + 运算符或者 concat() 方法拼接字符串。
-
替换:使用 replace() 方法基于正则表达式进行替换。
-
提取:使用 slice()、substring() 或 substr() 方法提取子字符串。
-
分割:使用 split() 方法按分隔符分割字符串为数组。
-
获取长度:使用 length 属性获取字符串长度。
-
获取索引:使用 charAt() 或 charCodeAt() 获取某索引的字符。
-
比较:使用 localeCompare() 进行语言环境的字符串比较。
-
开头和结尾:startsWith()/endsWith() 判断开头和结尾。
-
包含:indexOf() 判断是否包含子字符串。
-
重复:repeat() 方法重复字符串。
-
大小写转换:toUpperCase()/toLowerCase() 进行大小写转换。
-
去空格:trim() 去除两端空格,trimStart()/trimEnd() 去除单边。
-
编码:静态方法 fromCharCode() 将 Unicode 编码转为字符串。
-
格式化:使用模版字符串等格式化字符串内容。
对象
- 访问属性:使用点标记法(obj.prop)或方括号法(obj['prop'])访问对象属性。
- 设置属性:直接为对象赋值(obj.prop = 'value')来设置新属性或修改值。
- 删除属性:使用delete操作符删除对象属性(delete obj.prop)。
- 清空对象:将对象重新赋值为一个空对象({}),删除所有属性和方法。
- 合并对象:使用Object.assign()将多个对象属性合并到目标对象上。
- 遍历对象:使用for...in循环遍历对象所有可枚举属性。
- Object.keys():返回对象所有可枚举属性的键名数组。
- Object.values():返回对象所有可枚举属性的值数组。
- Object.entries():返回键值对数组。
- hasOwnProperty():检查对象自身是否包含某属性,不查原型链。
- 原型相关:设置__proto__修改原型,使用Object.create()基于原型创建新对象等。
- 冻结对象:使用Object.freeze()冻结对象,使其不可修改。
- 复制对象:使用展开语法、Object.assign()等复制对象。
对象创建方式
在 JavaScript 中,可以通过以下方式创建对象:
- 对象字面量
js
let obj = {
name: 'John',
age: 20
};
- new Object()
js
let obj = new Object();
obj.name = 'John';
- 构造函数
js
function Person(name, age) {
this.name = name;
this.age = age;
}
let obj = new Person('John', 20);
- Object.create()
js
let obj = Object.create(proto);
obj.name = 'John';
- ES6 class
js
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
}
let obj = new Person('John', 20);
- Object.assign()
js
let obj = Object.assign({}, { name: 'John', age: 20 })
- Object.fromEntries()
js
let obj = Object.fromEntries([['name','John'], ['age',20]])
这涵盖了 JavaScript 中创建对象的所有主流方式。根据需要选择合适的创建对象的方法。
map方法
-
new Map() - 创建map
-
map.set(key, value) - 设置键值对
-
map.get(key) - 获取对应键值
-
map.has(key) - 判断是否存在键
-
map.delete(key) - 删除键
-
map.clear() - 清空所有键值对
-
map.size - 获取大小长度
流程控制
- if语句
js
if (score > 90) {
console.log('A');
} else if (score > 80) {
console.log('B');
} else {
console.log('C');
}
- switch语句(指定值的判断)
js
switch(fruit) {
case 'banana':
console.log('香蕉');
break;
case 'apple':
console.log('苹果');
break;
default:
console.log('其他水果');
}
- for循环
js
for (let i = 0; i < 5; i++) {
console.log(i);
}
- while循环
js
let i = 0;
while (i < 5) {
console.log(i);
i++;
}
- do-while循环
js
let i = 0;
do {
console.log(i);
i++;
} while (i < 5);
- for-in循环
js
for (let key in obj) {
console.log(key);
}
- for-of循环
js
for (let value of array) {
console.log(value);
}
- continue语句
js
for (let i = 0; i < 10; i++) {
if (i % 2 === 0) continue;
console.log(i);
}
- break语句
js
while (true) {
if (i > 3) break;
i++;
}
- return语句
js
function foo() {
console.log('Hello');
return;
}
- try-catch语句
js
try {
let num = prompt('输入一个数字');
console.log(num * 2);
} catch(err) {
console.log(err);
}
-
throw语句的主要作用是手动抛出异常。例如:
jsfunction test(x) { if(x < 0) { throw new Error('x不能为负数'); } }
这里使用throw抛出一个错误对象,可以在catch中捕获处理:
jstry { test(-1); } catch(error) { console.log(error.message); }
throw的使用场景:
- 抛出自定义错误,并在catch块处理。
- 参数校验失败时,抛出错误返回,避免继续执行。
- 异常情况打断函数执行逻辑时,抛出错误。
throw与return区别:
- return用于正常返回,throw用于异常返回
- return后函数继续执行,throw后函数停止
- return需要函数调用接收返回值,throw可在上层catch
13.debugger语句
ini
function test() {
let a = 1;
debugger;
a++;
}
14.三段式语句
css
(i<1) ? i = 0 : i;
for...of 与for....in的区别
for...in 和 for...of都是JavaScript中的循环语句,两者之间有以下几点主要区别:
-
for...in 用于遍历对象,for...of 用于遍历数组等可迭代对象。
-
for...in 循环遍历的是对象的键名,for...of遍历的是对象的键值。
-
for...in 可以遍历原型链上的键名,for...of只遍历对象自身的属性。
-
for...of可以与break、continue和return配合使用。
-
for...in 把数字索引也作为键名遍历出来。
-
for...of不支持普通对象,需要配合Object.keys()来遍历键名。
-
for...in 的性能不如 for...of。
例子:
js
// for...in
for (let key in obj) {
console.log(key);
}
// for...of
for (let value of arr) {
console.log(value);
}
总结一下,for...in更适合遍历对象,for...of更适合遍历数组。要根据遍历的场景选择合适的循环语句。
可迭代对象?
在 JavaScript 中,可迭代对象的特点是实现了@@iterator方法,满足可迭代协议。以下是常见的可迭代对象:
-
Array:数组都是可迭代对象,可以直接使用 for...of 遍历。
-
Map 和 Set:Map 和 Set 都可以直接用于 for...of 循环。
-
String:字符串可以被遍历,返回单个字符。
-
TypedArray:TypedArray 是数组视图,可以迭代。
-
arguments:函数的参数数组 arguments 也是可迭代的。
-
DOM NodeList:document.querySelectorAll() 返回的节点列表。
-
Generator:生成器函数返回的迭代器是可迭代对象。
可迭代对象的常见方法和属性:
- Symbol.iterator:返回迭代器方法
- entries():返回键值对迭代器
- values():返回值的迭代器
- keys():返回键的迭代器
- for...of:可直接用于for...of循环遍历
可迭代对象可以通过 for...of、spread、yield*、destructuring 等特性进行遍历,是 ES6 引入的重要概念。
DOM操作
常见dom操作
常见的DOM操作主要包括:
- 获取元素
- document.getElementById() - 通过id获取单个元素
- document.getElementsByClassName() - 通过class名称获取元素列表
- document.getElementsByTagName() - 通过标签名称获取元素列表
- document.querySelector() - 使用CSS选择器获取单个元素
- document.querySelectorAll() - 使用CSS选择器获取元素列表
- 修改元素
- element.innerHTML - 获取/修改元素内部HTML
- element.attribute - 获取/修改元素属性,如id、class等
- element.style - 修改元素样式
- element.setAttribute() - 设置元素属性
- element.classList - 操作元素类
- 创建元素
- document.createElement()
- document.createTextNode()
- 添加/删除元素
- parentNode.appendChild()
- parentNode.removeChild()
- parentNode.insertBefore()
- 事件操作
- element.addEventListener() - 添加事件监听
- element.removeEventListener() - 移除事件监听
掌握这些DOM操作方法,可以对网页中的元素进行获取、修改、添加、删除、事件绑定等操作
操作DOM属性
在 DOM 操作中,可以操作元素的以下常见属性:
-
id: 元素的唯一标识符,使用 getElementById() 获取元素
-
className:元素的 class 属性,用于设置/获取元素的 CSS class
-
style:行内 CSS 样式,通过设置 style 属性可以改变元素样式
-
title:鼠标悬停时显示的文字提示
-
href:用于 a 标签的链接地址
-
src:用于 img、script、iframe 等标签的资源路径
-
alt:图片没有加载成功时的替代文本
-
value:用于 input、textarea 等表单元素存储其值
-
type:可以改变按钮、输入框等的类型
-
disabled:禁用按钮及输入框等,不可点击
-
textContent:改变元素中的文本内容
-
innerHTML:插入或修改元素内部的 HTML
-
attributes:元素所有的属性节点
-
dataset:自定义数据属性
-
hidden:控制元素的显示/隐藏
这些常用属性都可以直接通过 DOM 操作改变,实现动态效果
在 DOM 操作中,修改和访问元素的属性是非常常见的需求。主要可以通过以下方式对 DOM 元素的属性进行操作:
- 使用
.属性
或[]
语法直接获取/设置属性值:
js
// 读取 id 属性
const id = element.id;
// 设置 class 属性
element.className = 'class1';
- 使用
getAttribute()
和setAttribute()
方法:
js
// 获取属性
const attr = element.getAttribute('attrName');
// 设置属性
element.setAttribute('attrName', 'value');
- 使用
hasAttribute()
查询属性是否存在:
js
if (element.hasAttribute('disabled')) {
// do something
}
- 使用
removeAttribute()
删除属性:
js
element.removeAttribute('disabled');
- 对 class 属性,可以使用
classList
对象进行操作:
js
element.classList.add('class1');
element.classList.remove('class2');
注意区分自定义属性 dataset 和标准属性的不同访问方式。
熟练使用属性操作,可以简化元素属性的读取和修改。
函数
JavaScript中的函数有以下几个重要的特性和类型:
- 回调函数:将函数作为参数,在特定事件触发时执行回调逻辑。
- 立即调用函数:定义完函数后,立即执行,常用作模块化。
- 函数声明与表达式:函数声明提前,函数表达式常用于回调。
- 递归函数:函数内调用自己,用于解决回溯问题。
- 高阶函数:操作其他函数的函数,如map、reduce等。
- 生成器函数:用function*定义,返回迭代器,可控制执行流程。
- 匿名函数:常用于回调,不需要函数名。
- 作用域:函数内部声明的变量,只在函数内可见,形成闭包环境。
- 参数:函数接收任意个参数,通过arguments访问所有参数。
- 返回值:函数通过return语句返回值,没有返回则为undefined。
JavaScript各种函数类型的使用示例:
- 回调函数
js
function add(a, b, callback) {
let res = a + b;
callback(res);
}
add(2, 3, function(res) {
console.log(res); // 5
});
- 立即调用函数表达式
js
(function() {
// do something
})();
- 函数声明
js
function sum(a, b) {
return a + b;
}
- 函数表达式
js
const sum = function(a, b) {
return a + b;
};
- 递归函数
js
function factorial(n) {
if (n === 1) return 1;
return n * factorial(n - 1);
}
- 高阶函数
js
const arr = [1, 2, 3];
const double = arr.map(function(item) {
return item * 2;
});
- 生成器函数
js
function* genFn() {
yield 1;
yield 2;
return 3;
}
8.箭头函数
css
const sum = (a, b) => {
return a + b;
};
异步编程
异步编程是 JavaScript 的重要概念,主要涉及:
- 同步与异步:
-
同步:代码按顺序逐行执行,前一个任务结束后再执行后一个任务。
-
异步:不需要等待前一个任务完成就可以执行后一个任务。
- JavaScript 的异步编程方式:
-
回调函数:将任务的回调函数作为参数传递。
-
事件监听:绑定事件回调,在事件触发时调用回调函数。
-
Promise:用 Promise 封装异步操作,在状态改变时触发回调。
-
async/await:async函数返回 Promise,await可等待 Promise 完成。
- Node.js 的异步编程:
-
回调函数:fs.readFile()、请求处理等接受回调函数。
-
事件发射器:EventEmitter 的 on 和 emit 用于异步事件处理。
-
Promise:util.promisify 将回调函数风格转为 Promise。
总之,异步编程可以提高性能和效率。掌握回调/Promise/async/await 的异步处理方法很重要。
JavaScript内置函数总结
-
setTimeout()/clearTimeout() - 计时器函数,用于设置延时执行代码。
-
setInterval()/clearInterval()- 计时器函数,用于设置重复执行代码。
-
JSON.stringify()/JSON.parse() - 将对象序列化为 JSON 字符串或反序列化。
-
encodeURI()/decodeURI()- 对整个 URI 进行编码或解码。
-
Object.keys()/Object.values()/Object.entries() - 遍历对象属性。
-
Object.assign() - 合并对象,用于浅拷贝。
-
Object.create() - 使用给定的原型创建对象。
-
Object.defineProperty() - 定义对象属性。
-
Object.freeze() - 冻结对象,使其不可改变。
-
Math.random() - 生成随机数。
-
Math.max()/Math.min() - 求最大/最小值。
-
Math.round()/Math.floor()/Math.ceil() - 数字四舍五入取整。
-
Array.from() - 将类数组对象转换为数组。
-
Array.of() - 使用参数创建数组。
-
Array.isArray() - 判断是否为数组。
-
eval() - 将字符串作为脚本代码执行。
-
parseInt() / parseFloat() - 将字符串转换为整数/浮点数。
-
isNaN() - 检查一个值是否是NaN。
-
isFinite() - 检查一个值是否为有限数字。
-
encodeURI() / decodeURI() - URL编码/解码。
-
encodeURIComponent() / decodeURIComponent() - URL组件编码/解码。
-
escape() / unescape() - 弃用的URL编码/解码函数。
-
Object() - 创建一个对象包装器。
-
Function() - 创建一个函数对象。
-
Boolean() - 将值转换为布尔值。
-
Number() - 将值转换为数字。
-
String() - 将值转换为字符串。
-
Date() - 创建一个日期对象。
-
RegExp() - 创建一个正则表达式对象。
-
Error() - 创建一个错误对象。
-
Array() - 创建一个数组对象。
-
Symbol() - 创建一个符号值。