JavaScript - day01学习笔记
作用域
了解变量和函数的可访问范围,掌握不同作用域的特点和使用场景
局部作用域
变量在特定代码块或函数内部的可见性范围
函数作用域
函数内部声明的变量只能在函数内部访问,形成独立的作用域空间
function counter(x, y) {
const s = x + y
console.log(s) // 18
}
counter(10, 8)
console.log(s) // 报错
核心要点:
- 函数内部变量外部不可见
- 参数也是局部变量
- 函数间变量相互隔离
- 函数执行完变量被回收
块作用域
使用 {} 包裹的代码块内声明的变量具有独立的可见性
{
let age = 18
console.log(age) // 正常
}
console.log(age) // 报错
核心要点:
let/const产生块级作用域var无块级作用域- 不同代码块变量隔离
- 推荐使用
let/const
全局作用域
在整个程序中最外层声明的变量,任何地方都可以访问
const name = '小明'
function sayHi() {
console.log('你好' + name) // 可访问
}
核心要点:
- 最外层声明的变量
- 所有作用域都可访问
- 避免全局变量污染
- 减少全局变量使用
作用域链
嵌套的作用域形成的层级结构,决定了变量的查找顺序
let a = 1
function f() {
let b = 2
function g() {
console.log(a, b) // 1, 2
}
g()
}
核心要点:
- 嵌套作用域形成链状结构
- 变量查找:当前 → 父级 → 全局
- 子级可访问父级,反之不行
- 底层变量查找机制
闭包
能够访问其他函数作用域中变量的函数,实现数据封装
function outer() {
let count = 1
return function() {
count++
console.log(`调用${count}次`)
}
}
const fn = outer()
fn() // 调用2次
核心要点:
- 内层函数 + 外层变量
- 实现数据私有化
- 外部可访问内部变量
- 注意内存泄漏问题
变量提升
JavaScript 引擎在代码执行前将变量和函数声明提升到作用域顶部的行为
console.log(str) // undefined
var str = 'hello'
console.log(num) // 报错
let num = 10
核心要点:
var声明会被提升let/const无变量提升- 推荐先声明后使用
- 使用
let/const避免问题
函数进阶
掌握函数的各种高级特性和使用技巧,提升代码质量和开发效率
函数提升
函数声明在代码执行前被提升到作用域顶部的特性
foo() // 正常
function foo() {
console.log('函数提升')
}
bar() // 报错
var bar = function() {}
核心要点:
- 函数声明会被提升
- 函数表达式不会提升
- 提升只在当前作用域
函数参数
函数接收和处理外部数据的各种方式和技巧
默认值
为函数参数设置默认值,增强函数的健壮性
function sayHi(name = "小明", age = 18) {
console.log(`我叫${name},${age}岁`)
}
核心要点:
- 形参赋值即为默认值
- 未传参使用默认值
- undefined 触发默认值
动态参数
使用 arguments 对象处理不确定数量的参数
function sum() {
let s = 0
for(let i = 0; i < arguments.length; i++) {
s += arguments[i]
}
return s
}
核心要点:
arguments是伪数组- 获取所有传入实参
- 适用于参数个数不确定
剩余参数
使用 ... 语法收集多余的参数到数组中
function config(baseURL, ...other) {
console.log(baseURL, other)
}
核心要点:
...语法收集多余参数- 得到的是真数组
- 必须放在参数最后
箭头函数
ES6 引入的简洁函数语法,具有特殊的 this 绑定行为
const fn = x => x * 2
const fn2 = (x, y) => ({x, y})
const getSum = (...arr) => arr.reduce((sum, num) => sum + num, 0)
核心要点:
- 简洁的函数表达式
- 无函数提升
- 无自己的
this和arguments - 简写语法:单参数省括号,单表达式省大括号
箭头函数参数
箭头函数中没有 arguments,只能使用 ... 动态获取实参
// 1. 利用箭头函数来求和
const getSum = (...arr) => {
let sum = 0
for (let i = 0; i < arr.length; i++) {
sum += arr[i]
}
return sum
}
const result = getSum(2, 3, 4)
console.log(result) // 9
箭头函数 this
箭头函数不绑定自己的 this,而是继承外层作用域的 this
const obj = {
name: '小明',
sayHi: function() {
const count = () => {
console.log(this) // 指向 obj
}
count()
}
}
核心要点:
- 不创建自己的 this
- 继承外层作用域的 this
- 普通函数 this 指向调用者
- 适合需要固定 this 的场景
解构赋值
从数组或对象中提取值并赋值给变量的简洁语法
数组解构
按照位置从数组中提取值并赋值给变量
let [a, b, c] = [1, 2, 3]
let [x, y, ...z] = [1, 2, 3, 4, 5]
核心要点:
- 批量声明变量
- 按位置对应赋值
- 支持默认值和剩余参数
- 变量多则 undefined,少则忽略
对象解构
按照属性名从对象中提取值并赋值给变量
const user = {name: '小明', age: 18}
const {name, age} = user
const {name: userName, age: userAge} = user
核心要点:
- 按属性名匹配
- 支持重命名
- 支持默认值
- 函数参数中常用
面向对象
使用构造函数和原型创建对象,实现代码的封装和复用
构造函数
用于创建对象的特殊函数,通过 new 关键字调用
function Person(name, age) {
this.name = name
this.age = age
this.sayHi = function() {
console.log(`我是${this.name}`)
}
}
const p1 = new Person('小明', 18)
核心要点:
- 使用 new 调用
- 首字母大写约定
- 返回新创建的对象
- return 在构造函数中无效
实例成员
每个实例对象独有的属性和方法
function Person() {
this.name = '小明'
this.sayHi = function() {
console.log('大家好~')
}
}
核心要点:
- 通过 this 添加的属性和方法
- 每个实例独立拥有
- 实例间互不影响
静态成员
属于构造函数本身的属性和方法,所有实例共享
function Person() {}
Person.eyes = 2
Person.walk = function() {
console.log('人都会走路...')
}
核心要点:
- 添加到构造函数本身
- 通过构造函数访问
- this 指向构造函数
- 适合公共特征和方法
内置构造函数
JavaScript 内置的用于创建特定类型对象的构造函数
Object
创建普通对象的构造函数,提供对象操作的各种方法
const user = new Object({name: '小明', age: 15})
const student = {name: '杜子腾', age: 21} // 推荐
核心要点:
- 推荐字面量创建对象
Object.assign合并对象Object.keys/values获取键值- 语法简写更简洁
Array
创建数组对象的构造函数,提供丰富的数组操作方法
// 构造函数创建数组
let arr = new Array(5, 7, 8)
// 字面量方式创建数组
let list = ['html', 'css', 'javascript'] // 推荐
-
推荐使用字面量方式声明数组,而不是
Array构造函数 -
实例方法
forEach用于遍历数组,替代for循环 (重点)// forEach 就是遍历 加强版的for循环 适合于遍历数组对象 const arr = ['red', 'green', 'pink'] const result = arr.forEach(function (item, index) { console.log(item) // 数组元素 red green pink console.log(index) // 索引号 }) // console.log(result) -
实例方法
filter过滤数组单元值,生成新数组(重点)<body> <script> const arr = [10, 20, 30] // const newArr = arr.filter(function (item, index) { // // console.log(item) // // console.log(index) // return item >= 20 // }) // 返回的符合条件的新数组 const newArr = arr.filter(item => item >= 20) console.log(newArr) </script> </body> -
实例方法
map迭代原数组,生成新数组(重点) -
实例方法
join数组元素拼接为字符串,返回字符串(重点) -
实例方法
find查找元素, 返回符合测试条件的第一个数组元素值,如果没有符合条件的则返回 undefined(重点) -
实例方法
every检测数组所有元素是否都符合指定条件,如果所有元素都通过检测返回 true,否则返回 false(重点) -
实例方法
some检测数组中的元素是否满足指定条件 如果数组中有元素满足条件返回 true,否则返回 false -
实例方法
concat合并两个数组,返回生成新数组 -
实例方法
sort对原数组单元值排序 -
实例方法
splice删除或替换原数组单元 -
实例方法
reverse反转数组 -
实例方法
findIndex查找元素的索引值
包装类型
在 JavaScript 中的字符串、数值、布尔具有对象的使用特征,如具有属性和方法,如下代码举例
// 字符串类型
const str = 'hello world!'
// 统计字符的长度(字符数量)
console.log(str.length)
// 数值类型
const price = 12.345
// 保留两位小数
price.toFixed(2) // 12.34
之所以具有对象特征的原因是字符串、数值、布尔类型数据是 JavaScript 底层使用 Object 构造函数“包装”来的,被称为包装类型
String
String 是内置的构造函数,用于创建字符串。
<script>
// 使用构造函数创建字符串
let str = new String('hello world!');
// 字面量创建字符串
let str2 = '你好,世界!';
// 检测是否属于同一个构造函数
console.log(str.constructor === str2.constructor); // true
console.log(str instanceof String); // false
</script>
总结:
-
实例属性
length用来获取字符串的度长(重点) -
实例方法
split('分隔符')用来将字符串拆分成数组(重点) -
实例方法
substring(需要截取的第一个字符的索引[,结束的索引号])用于字符串截取(重点) -
实例方法
startsWith(检测字符串[, 检测位置索引号])检测是否以某字符开头(重点) -
实例方法
includes(搜索的字符串[, 检测位置索引号])判断一个字符串是否包含在另一个字符串中,根据情况返回 true 或 false(重点) -
实例方法
toUpperCase用于将字母转换成大写 -
实例方法
toLowerCase用于将就转换成小写 -
实例方法
indexOf检测是否包含某字符 -
实例方法
endsWith检测是否以某字符结尾 -
实例方法
replace用于替换字符串,支持正则匹配 -
实例方法
match用于查找字符串,支持正则匹配
注:String 也可以当做普通函数使用,这时它的作用是强制转换成字符串数据类型。
Number
Number 是内置的构造函数,用于创建数值。
<script>
// 使用构造函数创建数值
let x = new Number('10')
let y = new Number(5)
// 字面量创建数值
let z = 20
</script>
总结:
- 推荐使用字面量方式声明数值,而不是
Number构造函数 - 实例方法
toFixed用于设置保留小数位的长度
综合应用
将各种 JavaScript 特性结合使用,解决实际开发问题
链式调用
将多个数组方法连接起来,实现复杂的数据处理流程
const result = numbers
.map(num => num * 2)
.filter(num => num > 5)
.map(num => num + 1)
.reduce((sum, num) => sum + num, 0)
数据转换
使用数组方法对数据进行格式化和转换
const userNames = users.map(user => user.name)
const formattedUsers = users.map(user => ({
...user,
isAdult: user.age >= 18,
nameWithAge: `${user.name} (${user.age})`
}))
1046

被折叠的 条评论
为什么被折叠?



