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]);
}

breakcontinue 语句是仅有的可“跳出”代码块的 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表示不区分大小写

常用于两个方法

搜索匹配 返回字符串的位置

# 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

# letvar 的区别

  1. 作用域:

    • let块级作用域,只在最近的 {} 内有效。
    • var函数作用域,在声明的函数内都有效(如果不在函数中声明,则为全局作用域)。
    {
        let a = 10;
        var b = 20;
    }
    console.log(b); // 20
    console.log(a); // ReferenceError: a is not defined
    
  2. 变量提升:

    • var 会发生变量提升(在代码执行前被提升到作用域顶部),但值为 undefined
    • let 也会被提升,但会进入一个“暂时性死区(TDZ)”,在声明前访问会抛出 ReferenceError
    console.log(a); // undefined
    var a = 10;
    
    console.log(b); // ReferenceError: Cannot access 'b' before initialization
    let b = 20;
    
  3. 重复声明:

    • var 允许在同一作用域重复声明变量。
    • let 在同一作用域内不允许重复声明。
    var x = 10;
    var x = 20; // 合法
    
    let y = 30;
    // let y = 40; // SyntaxError: Identifier 'y' has already been declared
    
  4. 全局对象属性:

    • 使用 var 声明的全局变量,会成为 window(浏览器环境)的属性。
    • 使用 let 声明的全局变量,不会成为 window 的属性。
    var x = 10;
    let y = 20;
    
    console.log(window.x); // 10
    console.log(window.y); // undefined
    

# 共同点:

  • 都可以用来声明变量。
  • 都支持任意类型的赋值(stringnumber 等)。
  • 都允许在块、函数或全局作用域中使用。

# letconst 的区别

# 区别:

  1. 是否可重新赋值:

    • let 声明的变量可以重新赋值。
    • const 声明的变量不能重新赋值,但如果是对象或数组,其内容是可以修改的。
    let a = 10;
    a = 20; // 合法
    
    const b = 30;
    // b = 40; // TypeError: Assignment to constant variable.
    
    const obj = { key: "value" };
    obj.key = "newValue"; // 合法,因为对象的属性可以更改
    
  2. 声明时是否必须初始化:

    • let 声明后可以不立即赋值。
    • const 声明时必须立即赋值。
    let x;
    x = 10; // 合法
    
    // const y; // SyntaxError: Missing initializer in const declaration
    const y = 20;
    

# 共同点:

  • 都是块级作用域。
  • 都不会变量提升(存在“暂时性死区”)。
  • 都不能重复声明。

# varconst 的区别

# 区别:

  1. 作用域:
    • var 是函数作用域。
    • const 是块级作用域。
  2. 是否可重新赋值:
    • var 声明的变量可以重新赋值。
    • const 声明的变量不能重新赋值。
  3. 变量提升:
    • var 会被提升,初始化为 undefined
    • const 会进入“暂时性死区”,声明前访问会报错。
  4. 全局对象属性:
    • var 声明的全局变量会成为 window 的属性。
    • const 声明的全局变量不会成为 window 的属性。

# 共同点:

  • 都可以声明变量。
  • 都支持任意类型的赋值。

# 总结表格

特性 var let const
作用域 函数作用域 块级作用域 块级作用域
变量提升 有,值为 undefined 有,TDZ 有,TDZ
是否可重复声明 可以 不可以 不可以
是否可重新赋值 可以 可以 不可以(对象属性可变)
全局对象属性
声明时初始化 可选 可选 必须

根据需求选择适合的声明方式:

  • 一般优先使用 const,只在需要改变值时使用 let
  • 避免使用 var,因为其行为可能引发意外错误。