ECMAScript:JS的核心内容,描述了语言的基础语法,比如var,for,数据类型(数组、字符串)
文档对象模型(DOM):DOM把整个HTML页面规划为元素构成的文档
浏览器对象模型 (BOM):对浏览器窗口进行访问和操作
一元运算符:正号+、负号-、++、--
二元运算符:算术运算符(加减乘除)、关系运算符(==、!=、>、<)
三元运算符:唯一的具有三个操作数的运算符。条件 ? 表达式1 : 表达式2
如果条件为真,则返回表达式1的值,否则返回表达式2的值。
switch-case-default
要判断某一个变量 等于 某一个值的时候使用
必须写break
性能好,可以精准匹配
switch (要判断的变量) {
? ?case 情况1:
? ? ?情况1要执行的代码
? ? ?break;
? ?case 情况2:
? ? ?情况2要执行的代码
? ? ?break;
?
? ?default:
? ? ?上述情况都不满足的时候执行的代码
}
?
let code = 1
?switch (code) {
? ?case 0:
? ? ?document.write('未付款');
? ? ?break;
? ?case 1:
? ? ?document.write('已付款');
? ? ?break;
? ?case 2:
? ? ?document.write('已发货');
? ? ?break;
? ?case 3:
? ? ?document.write('已完成');
? ? ?break;
?
? ?default:
? ? document.write('未知状态');
}
while
当条件满足时执行,一旦不满足就不执行
语法:while(条件){满足添加就执行}
满足条件就执行,所以我们写的时候要设定一个边界值,不然会出现死循环
do-while
和while类似,但是do-while循环是先不管条件,直接执行一次,然后再开始进行条件判断
语法:do{要执行的代码} while (条件)
for循环
也是循环的结构
语法:for(var i=0;i<10;i++){要执行的代码}
(把初始化,条件判断,自身改变) 写在一起了
先赋初始值,然后判断,符合条件执行代码,执行完改变自身,然后再赋值再判断,以此类推
数据封装类对象:Object
、Array
、Boolean
、Number
、String
其他对象:Function
、Arguments
、Math
、Date
、RegExp
、Error
ES6新增对象:Symbol
、Map
、Set
、Promise
、Proxy
、Reflect
常用的有:
Math:
Math.max()
:返回一组数字中的最大值。
Math.min()
:返回一组数字中的最小值。
Math.abs()
:返回一个数的绝对值。
Math.sqrt()
:返回一个数的平方根。
Date:
new Date()
:创建一个表示当前日期和时间的 Date 对象。
getFullYear()
:获取 Date 对象的年份。
getMonth()
:获取月份(0-11,0 表示一月)。
getDate()
:获取日期(1-31)。
getDay()
:获取星期几(0-6,0 表示星期日)。
getHours()
:获取小时(0-23)。
getMinutes()
:获取分钟(0-59)。
getSeconds()
:获取秒(0-59)。
getTime()
:返回自 1970 年 1 月 1 日 00:00:00 UTC 起至当前时间的毫秒数。
setFullYear()
:设置年份。
setMonth()
:设置月份。
setDate()
:设置日期。
setHours()
:设置小时。
setMinutes()
:设置分钟。
setSeconds()
:设置秒。
Array:
concat()
:连接两个或多个数组,并返回一个新数组。
join()
:将数组中的所有元素连接成一个字符串。
pop()
:删除并返回数组的最后一个元素。
push()
:向数组的末尾添加一个或多个元素,并返回新的长度。
shift()
:删除并返回数组的第一个元素。
unshift()
:向数组的开头添加一个或多个元素,并返回新的长度。
reverse()
:颠倒数组中元素的顺序。
sort()
:对数组进行排序。
slice()
:选取数组的一部分,并返回一个新数组。
splice()
:删除、替换或插入元素到数组中,并返回被删除的元素组成的新数组。
indexOf()
:返回指定元素在数组中首次出现的索引。
lastIndexOf()
:返回指定元素在数组中最后一次出现的索引。
forEach()
:对数组中的每个元素执行一个函数。
// 1.没有返回值
// 2.不能使用break
// 3.遍历的是item
let arr = ['a','b','c']
let res = arr.forEach(item=>{
? ?console.log(item)
? ?break;
? ?return item + '0'
})
console.log(res)
map()
:对数组中的每个元素执行一个指定的函数,并返回一个新数组。
// 1.有返回值(数组)默认return是undefined
// 2.接受的参数是一个函数(key,value)
// 3.不能用break打断
let arr = ['a','b','c']
let res = arr.map((value,key)=>{
? ?return value + '0'
})
console.log(res)
filter()
:根据指定条件过滤数组中的元素,并返回一个新数组。
let a = [1,2,3,14,15]
// current当前值;index当前值的下标;array这个数组对象
let b = a.filter((current,index,array)=>{
? ?return current > 10
})
console.log(a)
console.log(b)
reduce()
:从左到右对数组中的每个元素执行一个归并操作,返回一个累计的值。
reduceRight()
:从右到左对数组中的每个元素执行一个归并操作,返回一个累计的值。
some()
:检查数组中是否至少有一个元素满足指定条件。
every()
:检查数组中的所有元素是否都满足指定条件。
find()
:返回数组中满足指定条件的第一个元素。
findIndex()
:返回数组中满足指定条件的第一个元素的索引。
includes()
:判断数组是否包含指定元素。
toString()
:将数组转换为字符串,并返回结果。
isArray()
:用于检测一个值是否为数组。
Vue中的7个变异方法:
pop()
、push()
、shift()
、unshift()
、reverse()
、sort()
、splice()
String:
length
:返回字符串的长度。
charAt()
:返回指定索引位置的字符。
concat()
:连接两个或多个字符串,并返回新的字符串。
substring()
:返回一个新的字符串,包含从开始索引到结束索引之间的字符。
toUpperCase()
:将字符串中的字母转换为大写。
toLowerCase()
:将字符串中的字母转换为小写。
trim()
:去除字符串两端的空白字符。
split()
:将字符串拆分为一个字符串数组,根据指定的分隔符进行拆分。
replace()
:替换字符串中的某个子字符串为另一个字符串。
startsWith()
:检查字符串是否以指定的子字符串开头。
endsWith()
:检查字符串是否以指定的子字符串结尾。
includes()
:检查字符串是否包含指定的子字符串。
charAt()
:获取字符串中指定索引位置的字符。
charCodeAt()
:获取字符串中指定索引位置的字符的 Unicode 编码值。
indexOf()
:返回指定子字符串在字符串中第一次出现的索引位置。
lastIndexOf()
:返回指定子字符串在字符串中最后一次出现的索引位置。
新增了块级作用域:let和const
箭头函数
扩展运算符和剩余参数...
解构赋值
模板字符串``
数据类型和数据结构:symbol、set、map
新增的对象、方法等,promise、proxy、Reflect等等
保存在栈内存中,保存的是具体的值。栈是线性数据结构
String、Number、Boolean、null、undefined
保存在堆内存中,声明一个引用类型变量时,保存的是引用数据类型的地址。堆是树形结构
Array、Function、Object、正则、日期等
例如,声明两个引用类型同时指向了一个地址的时候,修改其中一个那么另外一个也会改变
typeof():可以返回一个值的基本数据类型。只能判断基本数据类型,不能判断引用数据类型
instanceof():可以用来检查一个对象是否是某个构造函数的实例。只能判断引用数据类型,不能判断基本数据类型。语法例如是 'abc' instanceof String
constructor:检查一个对象的 constructor
属性来确定它的类型。('abc').constructor === String
Object.prototype.toString.call():返回一个值的详细类型信息,包括基本数据类型和对象类型。
Array.isArray:判断数组,如果是返回true
强制类型转换:
Number():把值转换成数字
String():把值转换成字符串
Boolean():把值转换成布尔值
parseInt():将字符串转换为整数
parseFloat():将字符串转换成浮点数
Array.from():将类数组对象或可迭代对象转换成真正的数组
隐式类型转换:js执行代码自动转换
数字和字符串:+结果为字符串;-、*、/时结果为数字
等号运算符比较不同的类型值,会被转换成相同的类型
数字和null:null转换为0
数字和undefined:undefined转换为NAN
1+‘2’ 是“12”,做了拼接
1-‘2’ 是 -1,当做减法时,js会尝试将字符串类型的2转成数值类型的2,所以就是-1
toString:是所有JS对象的方法,可以将任何类型的值转换为字符串。如果是null或undefined调用这个方法会输出 [object Undefined]
string:是一个全局函数,只能将非null和undefined值转换为字符串
变量的作用域:
let和const声明的变量具有块级作用域
var声明的变量存在变量提升,函数级作用域
变量重复声明
let和const声明的变量不允许被重复声明
var声明的变量可以被重复声明,后面声明的覆盖前面声明的
变量的赋值
var和let声明的变量可以进行重新赋值
const声明的变量是常量,不可以进行赋值
暂时性死区:避免变量在使用前就被意外地引用或访问
var不存在暂时性死区
let和const存在暂时性死区,只有等到声明变量的那一行代码出现,才可以获取和使用该变量,否则报错
可以的。虽然const声明的变量是常量,意味着引用是不能修改的,也就是不能将其重新赋值为另一个数组。但是可以修改数组本身的内容,进行增删改操作。
push()
: 在数组末尾添加一个或多个元素,并返回新数组的长度。
pop()
: 移除并返回数组末尾的元素。
unshift()
: 在数组开头添加一个或多个元素,并返回新数组的长度。
shift()
: 移除并返回数组开头的元素。
concat()
: 合并两个或更多数组,并返回新的合并后的数组,不会修改原始数组。
slice()
: 从数组中提取指定位置的元素,返回一个新的数组,不会修改原始数组。
splice()
: 从指定位置删除或替换元素,可修改原始数组。
indexOf()
: 查找指定元素在数组中的索引,如果不存在则返回-1。
lastIndexOf()
: 从数组末尾开始查找指定元素在数组中的索引,如果不存在则返回-1。
join()
: 将数组中的所有元素转为字符串,并使用指定的分隔符连接它们。
reverse()
: 颠倒数组中元素的顺序,会修改原始数组。
sort()
: 对数组中的元素进行排序,默认按照字母顺序排序,会修改原始数组。
循环的方法:
filter
forEach
map
some
every
reduce
扩展运算符(Spread operator):使用 ...
语法可以将一个数组展开成多个独立的元素,或者将多个元素合并为一个数组。
Array.from():通过类似数组的对象或可迭代对象创建一个新的数组。
Array.of():创建一个由传入参数组成的新数组。
find() 和 findIndex():用于在数组中查找满足指定条件的第一个元素及其索引。
includes():检查数组是否包含指定的元素,并返回布尔值。
fill():使用指定的值填充数组的所有元素。
flat() 和 flatMap():用于将嵌套的数组展平,减少维度。
以下方法的回调函数支持箭头函数语法。
filter()
: 创建一个新数组,其中包含符合条件的所有元素。
map()
: 创建一个新数组,其中包含对原始数组中的每个元素进行操作后的结果。
reduce()
: 将数组中的元素进行累积操作,返回一个单一的值。
forEach()
: 对数组中的每个元素执行提供的函数。
entries()、keys() 和 values():用于遍历数组的键值对、键和值。
数组解构赋值:可以通过解构赋值从数组中提取值并赋给变量。
数组的扩展属性:Array.prototype.length
可以被修改,Array.prototype[@@toStringTag]
返回 "Array"
使用new Set:用于存储一组唯一的值。使用new Set()将数组转为Set,再使用Array.from()转换为数组实现去重
const res1 = Array.from(new Set(arr));
for + indexOf:遍历数组,将当前元素与前面的元素进行比较,如果前面已经存在该元素,则跳过,否则将该元素添加到新数组中。
const unique2 = arr => { ?const res = []; ?for (let i = 0; i < arr.length; i++) { ? ?if (res.indexOf(arr[i]) === -1) res.push(arr[i]); } ?return res; }
filter + indexOf方法:筛选出不重复的元素,返回一个新的数组
const unique4 = arr => { ?return arr.filter((item, index) => { ? ?return arr.indexOf(item) === index; }); }
for + includes
const unique3 = arr => { ?const res = []; ?for (let i = 0; i < arr.length; i++) { ? ?if (!res.includes(arr[i])) res.push(arr[i]); } ?return res; }
两层for循环+splice
const unique1 = arr => { ?let len = arr.length; ?for (let i = 0; i < len; i++) { ? ?for (let j = i + 1; j < len; j++) { ? ? ?if (arr[i] === arr[j]) { ? ? ? ?arr.splice(j, 1); ? ? ? ?// 每删除一个树,j--保证j的值经过自加后不变。同时,len--,减少循环次数提升性能 ? ? ? ?len--; ? ? ? ?j--; ? ? } ? } } ?return arr; }
sort()
默认情况下,sort()
方法会将数组中的元素转换成字符串,并按照 Unicode 编码顺序进行排序。
arr = [1,2,12,25,112] console.log(arr.sort()); // [1, 112, 12, 2, 25]
常用方法,可以传递一个比较函数作为参数,以自定义排序方式。
arr = [1, 2, 12, 25, 112] // 升序 arr.sort(function (a, b) { ? ?return a - b }) console.log(arr); // [1, 2, 12, 25, 112] ? // 降序 arr.sort(function (a, b) { ? ?return b - a }) console.log(arr); // [112, 25, 12, 2, 1]
reverse():反转数组,也就是逆置
冒泡排序
通过不断比较相邻的两个元素,将较大(或较小)的元素逐步向右(或向左)移动,就像气泡在水中慢慢上升一样,最终使得整个数组按照升序(或降序)排列。
function bubblingSort(arr) { ?// 外层循环负责循环的次数。由于最后一个一定是最大的数,所以最后一个可以不用排。因此循环的次数是length - 1 ?for(var i = 0; i < arr.length - 1; i++) { ? ?// 内层循环负责两两比较 ? ?for(var j = 0; j < arr.length - i - 1; j++) { ? ? ?// 如果发现前一个数比后一个数大,则交换位置 ? ? ?if(arr[j] > arr[j + 1]) { ? ? ? ?var temp = arr[j] ? ? ? ?arr[j] = arr[j + 1] ? ? ? ?arr[j + 1] = temp ? ? } ? } } ?// 返回排好序的数组 ?return arr; }
快速排序
实现原理:先从数组中随便选择一个元素(通常是数组的第0项),作为基准元素。然后循环数组,把比基准元素小的放左边,比基准元素大的放右边
function fastSort(arr) { ?// 如果只有一个元素直接返回 ?if(arr.length <= 1) return arr; ?// 假设第0个元素就是标杆 ?var pivot = arr[0]; ?// 声明两个数组比标杆元素小的放左边,比标杆元素大的放右边 ?var left = []; ?var right = []; ?// 循环数组,比标杆元素小的放左边,比标杆元素大的放右边 ?for(var i = 1; i < arr.length; i++) { ? ?if(arr[i] < pivot) { ? ? ?left.push(arr[i]); ? } else { ? ? ?right.push(arr[i]); ? } } ?// 递归调用,把比标杆元素小的放左边,比标杆元素大的放右边 ?var arr2 = fastSort(left).concat(pivot, fastSort(right)); ?// 改变原有数组中的元素 ?for(var i = 0; i < arr2.length; i++) { ? ?arr[i] = arr2[i]; } ?return arr; }
选择排序
实现原理:
遍历数组,将第一个元素设为当前最小元素。
从第二个元素开始,依次与当前最小元素进行比较,找到最小的元素。
将最小元素与当前位置的元素进行交换,将最小元素放置在已排序部分的末尾。
重复上述步骤,每次从未排序的部分选择出一个最小元素放置在已排序部分的末尾,直到整个数组排序完成
function selectSort(arr) { ?for(var i = 0; i < arr.length - 1; i++) { ? ?// 先假设第i个位置的元素是最小元素,然后保存其下标 ? ?var minIdx = i; ? ?// 内层循环负责两两比较 ? ?for(var j = i + 1; j < arr.length; j++) { ? ? ?// 如果发现有比假设的最小元素小的元素 ? ? ?if(arr[j] < arr[minIdx]) { ? ? ? ?// 则立即更新最小位置的下标 ? ? ? ?minIdx = j; ? ? } ? } ? ?// 交换位置 ? ?var temp = arr[i]; ? ?arr[i] = arr[minIdx]; ? ?arr[minIdx] = temp; } ?return arr; }
插入排序
实现原理:依次从数组中取出一个元素,然后从右向左依次查找,直到找到比它小的元素,将其插入到对应的位置
function insertSort(arr) { ?for (var i = 1; i < arr.length; i++) { ? ?// 依次从数组中取出一个元素 ? ?var curValue = arr[i]; ? ?// 指针依次向左移动一格(即从右向左依次查找) ? ?var j = i - 1; ? ?while(j >= 0 && curValue < arr[j]) { ? ? ?// 将当前找到的元素右移一格,空出当前的位置 ? ? ?arr[j + 1] = arr[j]; ? ? ?j--; ? } ? ?// 将当前找到的元素插入到正确的位置 ? ?arr[j + 1] = curValue; } ?return arr; }
归并排序
实现原理:先对数组进行拆分,拆分到每个数组中只有一个元素则停止拆分。然后在对拆分后数组按顺序进行合并
function mergeSort(arr) { ?// 如果数组的长度小于等于1,则直接返回 ?if(arr.length <= 1) return arr; ? ?// 将数组从中间进行拆分 ?var mid = Math.floor(arr.length / 2); ?// 递归拆分左边数组 ?var left = mergeSort(arr.slice(0, mid)); ?// 递归拆分右边数组 ?var right = mergeSort(arr.slice(mid)); ? ?// 递归进行拆分合并 ?var arr2 = merge(mergeSort(left), mergeSort(right)); ?// 修改原数组 ?for(var i = 0; i < arr2.length; i++) { ? ?arr[i] = arr2[i]; } ?return arr; } ? // 合并数组方法 function merge(left, right) { ?// 先声明一个空数组 ?var result = []; ?// 不断的从拆分的数组中取元素进行比较,直到其中一边没有元素为止 ?while(left.length > 0 && right.length > 0) { ? ?// 对拆分后的数组元素进行比较,小的放左边,大的放右边 ? ?if(left[0] <= right[0]) { ? ? ?result.push(left.shift()); ? } else { ? ? ?result.push(right.shift()); ? } } ?// 将剩余的数组元素添加到结果数组(因为比较完以后有可能左边会有剩余元素或者右边会有剩余元素) ?return result.concat(left, right); }
slice()
方法返回一个新数组,包含从原数组中指定的开始位置到结束位置(不包括结束位置)的元素,不会修改原数组。
数组的截取(不包含结束位置),返回新数组,不会修改原数组
splice()
方法通过删除或替换现有元素或者添加新元素来修改原数组。它会返回被删除的元素组成的数组。
删除或替换修改原数组,会返回被删除的元素组成的数组
相同点:
Map和forEach都是循环遍历数组中的的每一项
每次执行匿名函数都支持3个参数 (item,index,原数组)
匿名函数中的this都是指向window的
区别:
map有返回值,有映射的效果,返回一个新的数组,不改变原数组。适用于需要生成新数组,且新数组的元素是对原数组进行某种转换的情况,比如对数组中的每个元素进行计算并返回一个新数组
forEach没有返回值return是不起作用的,不改变原数组,只用来遍历。适用于需要遍历数组但不需要生成新数组的情况,比如在循环中执行一些操作。
终止forEach可以使用try-catch抛出异常并结束循环
for...in:可以用来遍历数组、对象等可迭代对象。
遍历数组的话,输出的是数组元素的下标;
遍历对象的话,输出的是对象的键
// 数组
const arr = ['a','b','c']
?for(let i in arr){
? ?console.log(i);
}
?
// 对象
const obj = { a: 1, b: 2, c: 3 }
?for (let i in obj) {
? ?console.log(i); // 输出键名
? ?console.log(obj[i]); // 输出键值
}
for...of:ES6引进的新特性。只能遍历数组,输出的是数组的元素
不能遍历对象,因为没有interator接口
// 数组
const arr = ['a','b','c']
for(let n of arr){
? ?console.log(n);
}
循环数组嵌套对象
const arrObj = [
? { id: 1, name: '张三' },
? { id: 2, name: '李四' },
? { id: 3, name: '王五' }
]
?for (let nObj of arrObj) {
? ?for (let n in nObj){
? ? ?console.log(nObj[n]); // 输出每个对象的键值
? }
}
length
:返回字符串的长度。
const str = "Hello";
console.log(str.length); // 5
charAt(index)
:返回指定索引位置的字符。
const str = "Hello";
console.log(str.charAt(1)); // e
concat(string1, string2, ...)
:将多个字符串连接起来。
const str1 = "Hello";
const str2 = " World";
console.log(str1.concat(str2)); // Hello World
toUpperCase()
:将字符串转换为大写。
const str = "Hello";
console.log(str.toUpperCase()); // HELLO
toLowerCase()
:将字符串转换为小写。
const str = "Hello";
console.log(str.toLowerCase()); // hello
substring(startIndex, endIndex)
:提取从 startIndex
到 endIndex
(不包括)之间的子字符串。
const str = "Hello World";
console.log(str.substring(6, 11)); // World
indexOf(substring, startIndex)
:返回指定子字符串第一次出现的索引位置。如果找不到,则返回 -1。
const str = "Hello World";
console.log(str.indexOf("o")); // 4
console.log(str.indexOf("z")); // -1
replace(oldValue, newValue)
:将字符串中的指定值替换为新值,只替换第一个匹配项。
const str = "Hello World";
console.log(str.replace("World", "Universe")); // Hello Universe
split(separator)
:将字符串分割为子字符串数组,使用 separator
参数作为分隔符。
const str = "Hello,World,Universe";
console.log(str.split(",")); // ["Hello", "World", "Universe"]
trim()
:去除字符串两端的空格。
const str = " ? Hello ? ";
console.log(str.trim()); // Hello
startsWith(searchString, position)
:判断字符串是否以指定的内容开头。可选的 position
参数指定从哪个索引位置开始进行匹配。
const str = "Hello World";
console.log(str.startsWith("Hello")); // true
console.log(str.startsWith("World")); // false
endsWith(searchString, position)
:判断字符串是否以指定的内容结尾。可选的 position
参数指定从哪个索引位置结束进行匹配。
const str = "Hello World";
console.log(str.endsWith("World")); // true
console.log(str.endsWith("Hello")); // false
includes(searchString, position)
:判断字符串中是否包含指定的内容。可选的 position
参数指定从哪个索引位置开始进行匹配。
const str = "Hello World";
console.log(str.includes("Hello")); // true
console.log(str.includes("Universe")); // false
slice(startIndex, endIndex)
:提取从 startIndex
到 endIndex
(不包括)之间的子字符串。
const str = "Hello World";
console.log(str.slice(6, 11)); // World
padStart(targetLength, padString)
:在字符串的开头添加指定的字符,直到字符串达到指定的长度。
const str = "Hello";
console.log(str.padStart(10, "X")); // XXXXHello
padEnd(targetLength, padString)
:在字符串的末尾添加指定的字符,直到字符串达到指定的长度。
const str = "Hello";
console.log(str.padEnd(10, "X")); // HelloXXXX
repeat(count)
:将字符串重复指定的次数。
const str = "Hello";
console.log(str.repeat(3)); // HelloHelloHello
console.log(typeof null) // object 表示为“无”对象0
console.log(typeof undefined) // undefined 表示“无”的原始值 NaN
已经声明,未赋值
let o;
console.log(o)
对象某个属性不存在
let obj = {}
console.log(obj.a)
函数调用,少传一个参数
function fn(a,b){
?console.log(a,b) ?
}
fn(4)
函数的默认返回值(就是函数没有返回值的时候)
function demo(){
? ?console.log("11")
}
console.log(demo())
手动释放内存
let obj = {}
obj = null
作为函数的参数(此参数不是对象)
原型链的顶端
console.log(typeof null); // object
console.log(typeof undefined); // undefined
console.log((null == undefined)); // true
console.log((null === undefined)); // false
undefined是应该有值,但是没有赋值;null表示一个空值
使用typeof判断类型的时候,undefined是undefined;null是object
null不是对象
但是typeof null会输出“object”类型,但这是JS存在的一个bug,最初使用32位系统的时候为了性能考虑,使用的是低位存储变量的类型信息,000开头代表是对象,null表示全零,所以会误判为object。