sidebar: auto
# JavaScript
# let与var 的区别
# 1. 作用域不同
var
具有 函数作用域 或 全局作用域。let
具有 块级作用域(如for
循环内的let i
,在for
外部无法访问)。var
声明的变量会挂载到window
对象上,而let
不会。
# 2. 变量提升 & 暂时性死区(TDZ)
var
声明的变量会 提升(Hoisting),并允许在声明前访问,值为undefined
。let
也会提升,但在 定义前访问会报错,进入 暂时性死区(Temporal Dead Zone, TDZ)。
# 3. 变量重复声明
- 同一作用域下,
let
不能重复声明 变量,否则会报错。 var
可以重复声明,但可能导致意外覆盖。
# 字符串
# 字符串的方法
# .length
属性返回字符串的长度
# .indexOf('target')
返回字符串中指定文本首次出现的索引(从0开始)
# .lastIndexOf('target')
查找最后一次出现的索引
# .search('target')
检索字符串中的字符串,返回匹配的位置
# .slice(2,3)
提取字符串的某个部分并在新字符串中返回被提取的部分
# .slice(-3,-2)
负数从结尾开始,-1开始
# .slice(9)
从参数开始 到最后一个
# .slice(-9)
从结尾开始到参数
# .substring(7,13)
类似slice,但是无法接受负的参数
# .substr(7,6)
类似slice,第二个参数规定被提取部分的长度
# .replace('a','b')
另一个值替换指定的值
不会改变原来的字符串 会返回新的字符串
大小写敏感 用 /i
所有匹配用/g
# .toUpperCase()
把字符转换为大写
# .toLowerCase()
把字符转换为小写
# .concat()
连接两个或多个字符串
# .trim()
删除开头和结尾的空白符
# .charAt()
返回指定下标位置的字符串
# .charCodeAt()
返回字符串中指定下标的字符的 unicode编码
# [0]
属性访问 下标字符
# .split(',')
把字符串转换为数组
如果参数是 ""(空字符串) ,字符转数组
# 字符串搜索
# .indexOf(‘target’)
返回指定文本在字符串中第一次出现位置的索引
# .lastIndexOf('target')
返回最后一次出现位置的索引
如果未找到 都返回-1
两个方法都接受第二个参数开始搜索
# .search('target')
返回字符串中搜索指定值并返回位置
search没有第二个参数
indexOf不能使用正则表达式
# .match(/target/g)
根据正则在字符串搜索匹配值,结果作为数组返回
# .includes('world',12)
如果字符串包含指定值,返回true
从第二个参数开始搜索
# .startsWith(‘hello’)
如果以指定字符串开头 返回true
# .endsWith('world')
如果以指定字符串结束 返回true
startsWith 和 endsWith 区分 大小写
# 数字
# 整数
整数精度为15位
# 小数
小数点后17位
浮点算数不一定精准
# 数学计算
10 + '10' = '1010' // 加法有字符 会转字符
10 - '10' = 0
10 * '10' = 100
'100' - '10' = 90
// 所有数字运算中 会尝试将字符串转换为数字
# NaN 非数值
var x = 100 / "apple"
# isNaN(x)
返回true,因为x不是数字
typeof NaN 返回 number
# Infinity
Infinity 或 - Infinity 是js在计算数时超出最大可能数范围时返回的值
var x = 2 / 0 // x将是Infinity
typeof Infinity 返回 number
# 十六进制
js会把前缀0x的数值常量解释为十六进制
var x = 0xFF // x将是255
# 数值可以是对象
var x = 123 // typeof x 返回 number
var y = new Number(123) // typeof y 返回 object
# BigInt
在整数末尾加n,或者调用BigInt()
var x = 12345678901234567890n
var y = BigInt(12345678901234567890)
typeof y = Bigint
不允许BigInt 和 Number 之间进行算数运算
BigInt不能有小数
可以写成十六进制、八进制和二进制
# Number.MAX_SAFE_INTEGER
2^53 -1 最大安全整数
# Number.MIN_SAFE_INTEGER
-2^53 +1 最小安全整数
# Number.isInterger(132)
如果参数是整数,则返回true
# Number.isSafeInterger(12345678901234567890)
如果参数是安全整数,则返回true
# 数字方法
# .toString()
将数字转为字符串返回
# .toFixed(2)
保留指定参数位数小数点
# .toExponential(4)
数字四舍五入并用指数表示法书写
# .toPrecision(4)
返回指定参数位数,小数点后几位的数字
# (12).valueOf()
let obj = new Number(6)
console.log(obj.valueOf()) // 数字可以是typeof = number或对象typeof = object
可以将Number对象转换为原始值
# 将变量转换为数字
# Number('12')
返回其参数转换而来的数字
# parseFloat('123.123')
解析参数返回浮点数 (小数
# parseInt('123.1 asd')
解析参数返回整数
如果带有非数字字符 都只返回第一个数字,如果非数字字符在开头 返回NaN
# 数字属性
# EPSILON
Number.EPSILON是大于1的最小浮点数与1之差
# MAX_VALUE
Number.MAX_VALUE是js中表示最大数字的常量
# MIN_VALUE
Number.MIN_VALUE是js中表示最小数字的常量
# POSITIVE_INFINITY
let x = 1 / 0
溢出时返回 POSITIVE_INFINITY
NEGATIVE_INFINITY
let y = -1 / 0
# NaN ,not a number (非数字)
let x = 10 / 'apple'
# 数组
array = [1,'a',..]
typeof = object
数组可以保存 对象、函数 、甚至数组
# 数组的属性
# length属性
返回数组的长度
遍历数组最安全的方法是 使用for循环 ,也可以使用Array.foreach()
# 添加数组元素
var arr = ['a','b']
arr.push('c')
arr[arr.length] = 'c'
// 添加最高索引可在数组中创建未定义的洞
arr[6] = '6'
如果使用命名索引 js会把数组重定义为标准对象
之后,所有数组的方法和属性将产生非正确的结果
var person = [];
person["firstName"] = "Bill";
# 避免new Array()
使用[] ,new使代码复杂化
# 如何识别数组
typeof arr = 'object'
# Array.isArray(arr)
是数组 返回 true
# arr instanceof Array
是数组 返回 true
# 数组方法
# .toString()
把数组转为数组值(逗号分割)的字符串
# .join(',')
把数组用参数的符号分割
# .pop()
从数组中删除最后一个元素
return 出最后一个元素
# .push()
在数组结尾向数组添加一个新的元素
return新数组的长度
# .shift()
删除第一个数组元素
return删除的元素
# .unshift()
在开头添加新元素
return 新数组的长度
# 删除元素
# delete arr[2]
删除指定下标的元素
会在数组留下未定义的空洞
# 拼接数组
# .splice()
第一个参数定义添加的位置
第二个参数定义从位置删除多少元素
其余参数定义要添加的元素
var arr = ['a', 'b', 'c', 'd']
arr.splice(2, 0, 'e', 'f', 'g')
>>
[
'a', 'b', 'e',
'f', 'g', 'c',
'd'
]
使用splice()来删除元素
不会留空洞
# 合并数组
# arr.concat(brr)
# 裁剪数组
# slice(1)
return从参数下标开始切出一段数组
创建新数组,不会改变元原数组
两个参数 ,开始和结束
# 数组排序
# sort()
以字母顺序对数组进行排序 数字会按第一位从小到大排
# reverse()
反转数组
# sort()
数字排序
points.sort(function(a, b){return a - b}); // 从小到大
随机顺序
points.sort(function(a, b){return 0.5 - Math.random()});
最大值
function arrayMax(arr){
return Math.max.apply(null,arr)
}
最小值
function arrayMin(arr){
reutrn Math.min.apply(null,arr)
}
对象数组排序
var cars = [
{type:"Volvo", year:2016},
{type:"Saab", year:2001},
{type:"BMW", year:2010}];
cars.sort(function(a, b){return a.year - b.year});
# 数组迭代
# .forEach()
会更改原数组
# .map()
创建一个新数组 不更改原有数组 不会对没有值的元素执行函数 {空位(empty slot)}
# 相同点
1都是循环数组中的每一项
2都支持三个参数 item,index,arr
3匿名函数中this都是指向window
4只能遍历数组
5都接受一个回调函数作为参数
# 不同点
1 foreach会改变原数组 map不会,map会分配内存空间存储新数组return
2 foreach的速度大于map
# .filter()
var nums = [23, 657, 123, 45, 1]
var over34 = nums.filter((item, index, arr) => {
return item > 34
})
# filter和map的区别
1功能
map是对数组每个元素执行相同的操作,并返回一个新的数组
filter是根据某个过滤条件过滤,并返回一个新的数组
2返回值
map返回和原有数组相同长度的数组
filter返回一个新的数组,其中仅包含符合条件的元素
# .reduce()
在每个数组元素上运行函数,以生成||减少它
在数组从左往右运行
不会减少原始数组
4个参数(总数[初始值/先前返回的值],item,index,array)
reduce方法能够接受一个初始值
arr.reduce(func,100)
# .reduceRight()
从右到左工作
# .every()
检查所有数组值是否通过测试
arr.every(item,index,array){
return item > 18
} // 返回一个布尔值
# .some()
检查某些数组值是否通过测试
arr.some(item,index,array){
return item > 18
} //返回一个布尔值
# some和every的区别
some是检测是否有满足条件的,every是检测所有都满足条件的
every一假即假some一真即真
# 数组Const
const声明数组 有块级作用域 同一作用域不能重复
const cars = ["Volvo", "BMW"]; // 允许
const cars = ["Volvo", "BMW"]; // 不允许
# js日期
var date = new Date()
getDate() 返回天 1-31
getDay() 周0-6
getFullYear() 年yyyy
getHours() 小时0-23
getMilliseconds() 毫秒0-999
getMinutes() 分钟0-59
getMonth() 月0-11
getSeconds() 秒 0-59
getTime() 时间戳
# UTC时间方法
getUTCDate() 返回UTC时间 等等
# 日期设置方法
setDate() setFullYear()等等
# js数学
# Math.PI
3.1415926..
# Math.round(3.14)
对参数进行四舍五入
# Math.pow(x,y)
返回的值是x的y次方
# Math.sqrt(x)
返回的值是x的平方根
Math.sqrt(64) //返回8
# Math.abs(x)
返回x的绝对值
# Math.ceil(x)
返回值是x向上取整
# Math.floor(x)
返回值是x向下取整
# Math.sin(x)
正弦 // 数学忘记了
# Math.cos(x)
余弦
# Math.min(0,1,3,5)
返回参数列表中最小值 //0
# Math.max(3,4,5,7)
返回参数列表中最大值 // 7
# Math.random()
返回0-1之间的一个随机数
包括0 不包括1
# 随机整数
Math.floor(Math.random()*10) // 0`9之间整数
# js逻辑
# Boolean()函数
Boolean(10>9) // 返回true
布尔可以是对象 会影响运行速度
var y = new Boolean(false)
# js比较
# 比较运算符
== 等于
=== 强等于 数据类型也相同
!= 不等于
!== 不相等或类型不相等
> 大于
< 小于
>= 大于等于
<= 小于等于
# 逻辑运算符
&& 与
|| 或
! 非
# 条件(三元)运算符
showElement?show:noShow
字符串和数字比较时会把字符串转换为数值,空字符转换为0,非数值转换为false的NaN
当比较两个字符串时,"2" 大于 "12",因为(按照字母排序)1 小于 2
# js条件
if(){
}else if () {
}else{
}
# Switch语句
switch(表达式){
case n:
代码块
break;
case n:
代码块
break;
default:
默认代码块
}
switch (new Date().getDay()) {
case 4:
case 5:
text = "周末快到了:)";
break;
case 0:
case 6:
text = "今天是周末~";
break;
default:
text = "期待周末!";
}
case使用严格的比较
default可以不是最后一个case ,但是 要加break;
# js For循环
for(var i = 0,
var j = 1 ;
// 语句一 可以初始化多个值 或者省略
i <= 100 ;
// 语句二 也可以省略,返回true 会重新开始循环 false则结束
// 如果省略语句二 需要提供一个 break ,不然循环永远不会结束
i++
// 递增或者递减初始变量的值
){
console.log(i,j)
}
# For/In循环
遍历对象的属性
var obj = {
name:'songth1ef',
age:18
}
for(let key in obj){
console.log(obj[key])
}
也能遍历数组
let arr = [23,54,67,7,89]
for(let index in arr){
console.log(arr[index])
}
# For Of 循环
# 遍历数组
let arr = [23, 54, 67, 7, 89]
for (let item of arr) {
console.log(item);
}
# 遍历字符串
let str = 'songth2ef'
for(let item of str){
console.log(item)
}
# While循环
while会一直循环代码块 只要指定的条件为true
while(条件){
执行的代码
}
# do/while
至少执行一次 因为在while之前使用了do
do{
执行的代码
}
while(条件);
do要写在while之前 不然会报错
# Break和Continue
Break被用于跳出switch语句
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
if (arr[i].age > 18) {
break
}
}
continue 中断循环中的一个迭代 如果发生指定条件 然后继续下一个迭代
for (let i = 0; i < arr.length; i++) {
if (arr[i].age === 18) {
continue
}
console.log(arr[i]);
}
break
和 continue
语句是仅有的可“跳出”代码块的 JavaScript 语句。
let text = ''
let i = 0
block: {
text += '^'
text += '^'
text += '^'
break block
text += '^'
}
console.log(text); // 输出 ^^^
# typeof
有5种可以包含值的
string number boolean object function
6种类型的对象
Object Date Array String Number Boolean
2种不能包含值的数据类型
null undefined
# 基本数据类型
string number boolean null undefined symbol
# 引用数据类型
Object Function Array Date RegExp
# typeof会返回的类型
string number boolean object undefined function symbol bigint
# constructor属性
constructor
属性返回所有 JavaScript 变量的构造函数。
# undefined
没有值的变量都是undefined 类型也是undefined
# 空值
let a = '' // 类型是string
Null
数据类型是对象
typeof null = object
可以设值未null清空对象 但是类型任然是对象
typeof undefined // undefined
typeof null // object
null === undefined // false
null == undefined // true
# js类型转换
# 数值转换为字符串
String(x)
x.toString()
# 布尔转换为字符串
String(true)
true.toString()
# 日期转换为字符串
String(date)
date.toString()
# 字符串转换为数值
Number("3.14")
parseInt() // 整数
parseFloat() //浮点数
# 一元+运算符
var y = '5'
var x = + y // x 是数字5
如果y不能转数字 则值为NaN
# 布尔转数值
Number(true) // 1
Number(false) // 0
# 日期转数字
d = new Date()
Number(d) // 返回 时间戳
d.getTime() // 同上
# 自动类型转换
+ - *
5 + null // 5
'5' + null = 5null
'5' + 2 // '52' 会将2转为字符
"5" - 2 // 3
'5' * '2' // 10
# 自动字符串转换
输出对象或变量时js自动调用toString()函数 数字和布尔也会被转换,但并不明显
document.getElementById("demo").innerHTML = myVar;
// 如果 myVar = {name:"Fjohn"} // toString 转换为 "[object Object]"
// 如果 myVar = [1,2,3,4] // toString 转换为 "1,2,3,4"
// 如果 myVar = new Date() // toString 转换为 "Thu Aug 01 2024 14:15:11 GMT+0800 (中国标准时间)"
// 如果 myVar = 123 // toString 转换为 "123"
// 如果 myVar = true // toString 转换为 "true"
// 如果 myVar = false // toString 转换为 "false"
'0' 转换为 逻辑 为 true
'' 转换为 数字为0 逻辑为false
[] 转换为 数字为0 逻辑为true
null 转换为 数字为0 逻辑为false
# js位运算符
运算符 | 名称 | 描述 |
---|---|---|
& | AND | 如果两位都是 1 则设置每位为 1 |
| | OR | 如果两位之一为 1 则设置每位为 1 |
^ | XOR | 如果两位只有一位为 1 则设置每位为 1 |
~ | NOT | 反转所有位 |
<< | 零填充左位移 | 通过从右推入零向左位移,并使最左边的位脱落。 |
>> | 有符号右位移 | 通过从左推入最左位的拷贝来向右位移,并使最右边的位脱落。 |
>>> | 零填充右位移 | 通过从左推入零来向右位移,并使最右边的位脱落。 |
操作 | 结果 | 等同于 | 结果 |
---|---|---|---|
5 & 1 | 1 | 0101 & 0001 | 0001 |
5 | 1 | 5 | 0101 | 0001 | 0101 |
5 ^ 1 | 4 | 0101 ^ 0001 | 0100 |
~ 5 | 10 | ~0101 | 1010 |
5 << 1 | 10 | 0101 << 1 | 1010 |
5 >> 1 | 2 | 0101 >> 1 | 0010 |
5 >>> 1 | 2 | 0101 >>> 1 | 0010 |
# & 与
两边都满足条件
true & true = 1
true & false = 0
# | 或
其中一边满足条件
false | true = 1
false | false = 0
# 位运算XOR
两边不相同返回1
true ^ true = 0
true ^ false = 1
位运算NOT(~)
~1 = -2
~0 = -1
~-1 = 0
~-2 = 1
~3 = -2
# 正则表达式
var patt = /songth1ef/i
搜索字符'songth1ef' i表示不区分大小写
常用于两个方法
# search()
搜索匹配 返回字符串的位置
# replace()
返回替换修改后的字符
正则表达式可以使你的搜索更强大
# 正则修饰符
i 大小写不敏感
g 全局匹配
m 多行匹配
# 正则表达式模式
[abc] 使用于方括号内任何字符
[0-9] 查找0-9的数字
(x|y) 查找由|分割的任何选项
# 元字符
\d 查找数字
\s 查找空白字符
\b 匹配单词边界
\uxxxx 查找16进制的unicode字符
# Quantifiers定义量词
n+ 匹配任何包含至少一个n的字符串
n* 匹配任何包含零个或多个n的字符串
n? 匹配任何包含零个或一个n的字符串
# test()
test()是一个正则表达式方法
返回true或false
var patt = /e/;
patt.test('The best things in life are free!')
由于字符串中有一个e 结果是 true
# exec()
exec() 找到指定文本返回找到的文本 否则返回null
patt.exec('The best things in life are free!') // 输出e
# 运算符优先级
乘法和除法的优先级高于加法和减法
先进行乘法运算
使用圆括号时 先计算圆括号内的运算
优先级相同从左向右
var num = '1' + 2 * 3
console.log(num); //16
console.log(typeof num); //string
优先级 | 运算符 | 例子 |
---|---|---|
18 | ( ) | (100 + 50) * 3 |
17 | . | person.name |
17 | [] | person["name"] |
17 | ?. | x ?. y |
17 | () | myFunction() |
17 | new | new Date("June 5,2022") |
16 | new | new Date() |
增量运算符后缀递增在前缀递增之前执行。 | ||
15 | ++ | i++ |
15 | -- | i-- |
14 | ++ | ++i |
14 | -- | --i |
NOT 运算符 | ||
14 | ! | !(x==y) |
14 | ~ | ~x |
一元运算符 | ||
14 | + | +x |
14 | - | -x |
14 | typeof | typeof x |
14 | void | void(0) |
14 | delete | delete myCar.color |
// 使用 void(0) 来防止<a>标签点击后的默认跳转行为
<a href="javascript:void(0)">Click me</a>
13 | ** | 10 ** 2 | |
---|---|---|---|
9 | in | "PI" in Math | |
---|---|---|---|
9 | instanceof | x instanceof Array |
# in
判断 对象中是否存在 属性
# instanceof
后面通常跟着一个构造函数或者一个类名
检查对象是否是某个类的实例,或者时候继承自该类
target instanceof Object
target instanceof Array
target instanceof Date
自定义构造函数
function Car(make, model) {
this.make = make;
this.model = model;
}
let myCar = new Car('Toyota', 'Corolla');
console.log(myCar instanceof Car); // true
# ??
var x = 0
console.log(x??y) // 0 x的值不是undefined或null则显示x
条件(三元)运算符 | |||
---|---|---|---|
2 | ? : | ? "yes" : "no" |
# js异常
# Throw和Try to Catch
try{
//供测试的代码块
}
catch(err){
// 处理错误的代码块
}
# js抛出错误
# throw
允许自定义错误
try {
if (true) {
throw 500
}
}
# catch
// name message
catch (err) {
console.log(err.name);
console.log(err.message);
}
# finally语句
try{}
catch(err){}
finally{
// 无论结果如何都会执行的代码块
}
# error
属性 name 和 message
错误名 | 描述 |
---|---|
EvalError | 已在 eval() 函数中发生的错误 |
RangeError | 已发生超出数字范围的错误 |
ReferenceError | 已发生非法引用 |
SyntaxError | 已发生语法错误 |
TypeError | 已发生类型错误 |
URIError | 在 encodeURI() 中已发生的错误 |
# js作用域
局部作用域
{}
// 所有 被 {}包裹的 都是 局部
全局作用域
var name ='name'
{
console.log(name)// 全局变量 任何位置都可以访问
}
自动全局
fn()
// 此处能使用name
function fn (){
name = 'name'
}
局部变量会在函数执行完成时被删除
全局变量会在关闭页面时被删除
函数参数也是函数内的局部变量
# hoisting
js可以在变量声明(var)之前使用它
let和const不会被提升
# 严格模式
"use strict"
不允许使用 未声明的变量 包括对象
删除变量(或对象、函数)是不允许的
重复参数名是不允许的
"use strict"
function x(p1,p1){
}
八进制数值文本不允许
转义字符不允许
写入只读属性不允许
写入只能获取的属性不允许
。。。
# this关键字
方法中 this指的是 所有者对象
单独情况下 this指的是 全局对象
在函数中 this 指的是全局对象
在函数中 严格模式下 this指的是 undefined
在事件中 this指的是 接收事件的元素
# 方法中的this
这里的this指的是person对象
var person = {
firstName: "Bill",
lastName : "Gates",
id : 678,
fullName : function() {
return this.firstName + " " + this.lastName;
}
};
# 单独的this
this指的是全局对象 [object Window]
# 函数中的this
this指的是全局对象 [object Window]
严格模式下 this指向undefined
# 事件处理中的this
this指的是接收此事件的html元素
# 对象方法绑定
this是person对象
显式函数绑定
# call()
# apply()
# 箭头函数
let func = (a,b)=>a*b
hello = ()=> 'hello'
this指向定义箭头函数的对象
# js类
始终使用关键字 class 创建类
始终添加名为constructor()的方法
class className{
constructor(){...}
}
class Car{
constructor(name,year){
this.name = name
this.year = year
}
}
在创建新对象时会自动调用constructor方法
# constructor方法
必须拥有确切名称的构造函数
创建新对象时自动执行
初始化对象属性
如果未定义构造函数方法 js会添加空的构造函数方法
# class方法
类方法的创建
class human {
constructor(){}
eat(){}
work(){}
}
可以向类方法发送参数
class human {
constructor(name, age) {
this.name = name
this.age = age
}
eat(food) {
return this.name + ' eating an ' + food
}
}
let st1 = new human('songth1ef', 18)
console.log(st1.eat('apple'));
# 模块(Modules)
依赖于 type='module' 使用import语句
<script type="module">
import message from './message.js'
</script>
# 命名导出
export const name = 'songth1ef'
const name = 'songth1ef'
export {name}
# 默认导出
const message = ()=>{
const name = 'songth1ef'
const age = 19
}
export default message
# 导入
从命名导出导入
import {name,age} from './person.js'
从默认导出导入
import message from './message.js'
# JSON
JavaScriptObjectNotation
{
"name":"songth1ef",
"skills":[
{"skill":"vue","years":"5"},
{"skill":"react","years":"5"}
]
}
json格式评估为js对象
# JSON.parse()
将json字符串转换为js对象
# js最佳实践
避免全局变量、new、===、eval()
在顶部声明
初始化变量
不要声明数值、字符串或布尔对象
# 请勿使用 new Object()
- 请使用 {} 来代替 new Object()
- 请使用 "" 来代替 new String()
- 请使用 0 来代替 new Number()
- 请使用 false 来代替 new Boolean()
- 请使用 [] 来代替 new Array()
- 请使用 /()/ 来代替 new RegExp()
- 请使用 function (){}来代替 new Function()
# 意识到自动类型转换
let x = 5 + "7" //'57'
为参数设置默认值
function func(x,y){
if(y === undefined){
y = 0
}
}
用default结束switch
避免使用eval()
# js常见错误
意外使用 =
var x = 0
if(x == 10)
if(x = 10) // true
浮点数
var a = 0.1
var b = 0.2
var c = a + b //结果不是0.3
var c = ( a*10 + b*10 ) / 10
不要对return语句换行
undefined不是null
# js性能
减少循环中的活动
var i
var length = arr.length
for(i = 0; i<=length; i ++){}
减少dom访问
var obj
obj = document.getElementById('demo')
缩减dom规模
避免不必要的变量
延迟js的加载
避免使用with
# js保留词
不能用来作为变量,标记或函数名
abstract | arguments | await* | boolean |
---|---|---|---|
break | byte | case | catch |
char | class* | const | continue |
debugger | default | delete | do |
double | else | enum* | eval |
export* | extends* | false | final |
finally | float | for | function |
goto | if | implements | import* |
in | instanceof | int | interface |
let* | long | native | new |
null | package | private | protected |
public | return | short | static |
super* | switch | synchronized | this |
throw | throws | transient | true |
try | typeof | var | void |
volatile | while | with | yield |
js对象、属性和方法
Array | Date | eval | function |
---|---|---|---|
hasOwnProperty | Infinity | isFinite | isNaN |
isPrototypeOf | length | Math | NaN |
name | Number | Object | prototype |
String | toString | undefined | valueOf |
事件
onblur | onclick | onerror | onfocus |
---|---|---|---|
onkeydown | onkeypress | onkeyup | onmouseover |
onload | onmouseup | onmousedown | onsubmit |
# js对象定义
在 JavaScript 中,几乎“所有事物”都是对象。
- 布尔是对象(如果用 new 关键词定义)
- 数字是对象(如果用 new 关键词定义)
- 字符串是对象(如果用 new 关键词定义)
- 日期永远都是对象
- 算术永远都是对象
- 正则表达式永远都是对象
- 数组永远都是对象
- 函数永远都是对象
- 对象永远都是对象
所有 JavaScript 值,除了原始值,都是对象。
# js原始值
string number bollean null undefined
创建对象的方式
let person = {
name:'songth1ef',
age:18
}
let person = new Object()
# js对象属性
obj.property
// 例如
person.name
person['name']
# for in 循环
let person = {
name: 'songth1ef',
age: 18,
job: 'front'
}
for (let key in person) {
let value = person[key]
console.log(key + ':' + value);
}
# for of 循环
使用 object.keys 或object.getOwnPropertyNames 方法获取键名的数组
// let arr = Object.keys(person)
let arr = Object.getOwnPropertyNames(person)
for (let key of arr) {
console.log(key + ':' + person[key]);
}
# 添加属性
person.language = 'chinese'
# 删除属性
delete person.age
会删除属性的值和属性本身
不能删除预定义的js对象属性 不会删除被继承的原型属性
# 对象方法
包含函数定义的属性
let person = {
name:'songth1ef',
eat:function(food){
return this.name + ' eatting ' + food
}
}
# this关键词
this指向拥有该函数的对象
# 访问对象方法
let obj = {
doST:function(){}
}
obj.doST() //访问对象的方法
let doST = obj.doST() // 也可
# 使用内建方法
let str = 'songth1ef'
console.log(str.toUpperCase());
# 显示对象
直接输出对象是 [object object]
# Object.values()显示对象
将对象的每一个键值添加到数组里 对象转为数组
# JSON.stringify()显示对象
不会将函数转为字符串 可以先用toString()
let obj = {
eat: function (food) {
console.log('eat' + food);
}
}
obj.eat = obj.eat.toString()
console.log(JSON.stringify(obj));
# 在循环中显示对象
for (let key in obj){
console.log(obj[key])
}
# js对象访问器
Getter和setter
# get关键字
let human = {
name: 'songth1ef',
age: 18,
get info() {
return this.name + ' age is ' + this.age
}
}
console.log(human.info);
# set关键字
let human = {
name: 'songth1ef',
age: 18,
get info() {
return this.name + ' age is ' + this.age
},
set info(info){
this.name = info.name
this.age = info.age
}
}
human.info = {name:'songth2ef',age:19}
console.log(human.info);
# defineProperty()
let human = {
name: 'songth1ef',
age: 18
}
Object.defineProperty(human, 'info', {
get: function () {
return this.name + ' age is ' + this.age
}
})
console.log(human.info);
# js对象构造器
function Human(name, age) {
this.name = name
this.age = age
}
// 大写字母开头构造函数
let person = new Human('songth1ef', 18)
console.log(person);
当一个新对象被创建时,this的值就会变成这个新对象
请不要把字符串创建为对象。它会拖慢执行速度。 而且typeof是object 。代码复杂化,冗长
# js对象原型
无法为已有的对象构造器添加新属性
使用prototype属性
function Human(name, age, sex) {
this.name = name
this.age = age
this.sex = sex
}
Human.prototype.language = 'chinese'
let pers0n = new Human('SONGTH2EF', 23, 'MAN')
console.log(pers0n.language);
console.log(Human.prototype); // Human{}
console.log(Human.prototype.__proto__); // {}
console.log(Human.prototype.__proto__.__proto__); // null
console.log(person.__proto__); // Human{}
请只修改您自己的原型。绝不要修改标准 JavaScript 对象的原型。
# Set
set集合是一组唯一值的集合
每个值在set中只能出现一次
可以容纳任何数据类型的值
# Set 方法
方法 | 描述 |
---|---|
new Set() | 创建新的 Set。 |
add() | 向 Set 中添加新元素。 |
delete() | 从 Set 中移除元素。 |
has() | 如果值存在则返回 true。 |
clear() | 从 Set 中移除所有元素。 |
forEach() | 为每个元素调用回调函数。 |
values() | 返回包含 Set 中所有值的迭代器。 |
keys() | 与 values() 相同。 |
entries() | 返回迭代器,其中包含 Set 中的 [value,value] 值值对。 |
属性 | 描述 |
---|---|
size | 返回 Set 中元素的数量。 |
typeof persons // 返回 object
# Map
方法 | 描述 |
---|---|
new Map() | 创建新的 Map 对象。 |
set() | 为 Map 中的键设置值。 |
get() | 获取 Map 对象中键的值。 |
clear() | 从 Map 中移除所有元素。 |
delete() | 删除由某个键指定的 Map 元素。 |
has() | 如果键存在于 Map 中,则返回 true。 |
forEach() | 为 Map 中的每个键/值对调用回调函数。 |
entries() | 返回迭代器对象,其中包含 Map 中的 [key, value] 键值对。 |
keys() | 返回迭代器对象,其中包含 Map 中的键。 |
values() | 返回迭代器对象,其中包含 Map 中的值。 |
属性 | 描述 |
---|---|
size | 返回 Map 元素的数量。 |
typeof fans // 返回 object
能够将对象用作键是 Map 的一项重要特性。
# ES5对象方法
// 以现有对象为原型创建对象
Object.create()
const prototypeObject = {
greet() {
console.log('Hello!');
}
};
const newObject = Object.create(prototypeObject);
newObject.greet(); // 输出 'Hello!'
// 添加或更改对象属性
Object.defineProperty(object, property, descriptor)
const obj = {};
Object.defineProperty(obj, 'name', {
value: 'John',
writable: true,
enumerable: true,
configurable: true
});
console.log(obj.name); // 输出 'John'
// 添加或更改对象属性
Object.defineProperties(object, descriptors)
Object.defineProperties(obj, {
'firstName': {
value: 'song',
writable: true,
enumerable: true,
configurable: true
},
'lastName': {
value: 'th1ef',
writable: false,
enumerable: true,
configurable: false
}
})
console.log(obj);
// 访问属性
Object.getOwnPropertyDescriptor(object, property)
let fN = Object.getOwnPropertyDescriptor(obj, 'firstName')
// 以数组返回所有属性
Object.getOwnPropertyNames(object)
let objKeys = Object.getOwnPropertyNames(obj)
console.log(objKeys);
console.log(Object.keys(obj));
// 访问原型
Object.getPrototypeOf(object)
const obj = {}
const proto = Object.getPrototypeOf(obj)
console.log(proto === Object.prototype);
// 以数组返回可枚举属性
Object.keys(object)
保护对象
// 防止向对象添加属性
Object.preventExtensions(object)
// 如果属性可以添加到对象,则返回 true
Object.isExtensible(object)
// 防止更改对象属性(不是值)
Object.seal(object)
// 如果对象被密封,则返回 true
Object.isSealed(object)
// 防止对对象进行任何更改
Object.freeze(object)
// 如果对象被冻结,则返回 true
Object.isFrozen(object)
# JavaScript 2025
# Q&A
# let
和 var
的区别
作用域:
let
是 块级作用域,只在最近的{}
内有效。var
是 函数作用域,在声明的函数内都有效(如果不在函数中声明,则为全局作用域)。
{ let a = 10; var b = 20; } console.log(b); // 20 console.log(a); // ReferenceError: a is not defined
变量提升:
var
会发生变量提升(在代码执行前被提升到作用域顶部),但值为undefined
。let
也会被提升,但会进入一个“暂时性死区(TDZ)”,在声明前访问会抛出ReferenceError
。
console.log(a); // undefined var a = 10; console.log(b); // ReferenceError: Cannot access 'b' before initialization let b = 20;
重复声明:
var
允许在同一作用域重复声明变量。let
在同一作用域内不允许重复声明。
var x = 10; var x = 20; // 合法 let y = 30; // let y = 40; // SyntaxError: Identifier 'y' has already been declared
全局对象属性:
- 使用
var
声明的全局变量,会成为window
(浏览器环境)的属性。 - 使用
let
声明的全局变量,不会成为window
的属性。
var x = 10; let y = 20; console.log(window.x); // 10 console.log(window.y); // undefined
- 使用
# 共同点:
- 都可以用来声明变量。
- 都支持任意类型的赋值(
string
、number
等)。 - 都允许在块、函数或全局作用域中使用。
# let
和 const
的区别
# 区别:
是否可重新赋值:
let
声明的变量可以重新赋值。const
声明的变量不能重新赋值,但如果是对象或数组,其内容是可以修改的。
let a = 10; a = 20; // 合法 const b = 30; // b = 40; // TypeError: Assignment to constant variable. const obj = { key: "value" }; obj.key = "newValue"; // 合法,因为对象的属性可以更改
声明时是否必须初始化:
let
声明后可以不立即赋值。const
声明时必须立即赋值。
let x; x = 10; // 合法 // const y; // SyntaxError: Missing initializer in const declaration const y = 20;
# 共同点:
- 都是块级作用域。
- 都不会变量提升(存在“暂时性死区”)。
- 都不能重复声明。
# var
和 const
的区别
# 区别:
- 作用域:
var
是函数作用域。const
是块级作用域。
- 是否可重新赋值:
var
声明的变量可以重新赋值。const
声明的变量不能重新赋值。
- 变量提升:
var
会被提升,初始化为undefined
。const
会进入“暂时性死区”,声明前访问会报错。
- 全局对象属性:
var
声明的全局变量会成为window
的属性。const
声明的全局变量不会成为window
的属性。
# 共同点:
- 都可以声明变量。
- 都支持任意类型的赋值。
# 总结表格
特性 | var | let | const |
---|---|---|---|
作用域 | 函数作用域 | 块级作用域 | 块级作用域 |
变量提升 | 有,值为 undefined | 有,TDZ | 有,TDZ |
是否可重复声明 | 可以 | 不可以 | 不可以 |
是否可重新赋值 | 可以 | 可以 | 不可以(对象属性可变) |
全局对象属性 | 是 | 否 | 否 |
声明时初始化 | 可选 | 可选 | 必须 |
根据需求选择适合的声明方式:
- 一般优先使用
const
,只在需要改变值时使用let
。 - 避免使用
var
,因为其行为可能引发意外错误。