JS由哪三部分组成?
-
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 = 1switch (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++){要执行的代码}
(把初始化,条件判断,自身改变) 写在一起了
-
先赋初始值,然后判断,符合条件执行代码,执行完改变自身,然后再赋值再判断,以此类推
-
-
JS有哪些内置对象?
-
数据封装类对象:
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()
:返回指定子字符串在字符串中最后一次出现的索引位置。
-
-
ES6有哪些新特性
-
新增了块级作用域:let和const
-
箭头函数
-
扩展运算符和剩余参数
...
-
解构赋值
-
模板字符串``
-
数据类型和数据结构:symbol、set、map
-
新增的对象、方法等,promise、proxy、Reflect等等
JS的数据类型
基本数据类型
-
保存在栈内存中,保存的是具体的值。栈是线性数据结构
-
String、Number、Boolean、null、undefined
引用数据类型
-
保存在堆内存中,声明一个引用类型变量时,保存的是引用数据类型的地址。堆是树形结构
-
Array、Function、Object、正则、日期等
-
例如,声明两个引用类型同时指向了一个地址的时候,修改其中一个那么另外一个也会改变
JS对数据类型的检测方法有哪些
-
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’ 和 1-‘2’ 的结果
-
1+‘2’ 是“12”,做了拼接
-
1-‘2’ 是 -1,当做减法时,js会尝试将字符串类型的2转成数值类型的2,所以就是-1
toString和String的区别
-
toString:是所有JS对象的方法,可以将任何类型的值转换为字符串。如果是null或undefined调用这个方法会输出 [object Undefined]
-
string:是一个全局函数,只能将非null和undefined值转换为字符串
let、const和var的区别
-
变量的作用域:
-
let和const声明的变量具有块级作用域
-
var声明的变量存在变量提升,函数级作用域
-
-
变量重复声明
-
let和const声明的变量不允许被重复声明
-
var声明的变量可以被重复声明,后面声明的覆盖前面声明的
-
-
变量的赋值
-
var和let声明的变量可以进行重新赋值
-
const声明的变量是常量,不可以进行赋值
-
-
暂时性死区:避免变量在使用前就被意外地引用或访问
-
var不存在暂时性死区
-
let和const存在暂时性死区,只有等到声明变量的那一行代码出现,才可以获取和使用该变量,否则报错
-
const声明数组可以push元素吗?
可以的。虽然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 - 1for(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); }
-
Array.slice() 与 Array.splice() 的区别
-
slice()
方法返回一个新数组,包含从原数组中指定的开始位置到结束位置(不包括结束位置)的元素,不会修改原数组。数组的截取(不包含结束位置),返回新数组,不会修改原数组
-
splice()
方法通过删除或替换现有元素或者添加新元素来修改原数组。它会返回被删除的元素组成的数组。删除或替换修改原数组,会返回被删除的元素组成的数组
数组中的Map和forEach的区别
-
相同点:
-
Map和forEach都是循环遍历数组中的的每一项
-
每次执行匿名函数都支持3个参数 (item,index,原数组)
-
匿名函数中的this都是指向window的
-
-
区别:
-
map有返回值,有映射的效果,返回一个新的数组,不改变原数组。适用于需要生成新数组,且新数组的元素是对原数组进行某种转换的情况,比如对数组中的每个元素进行计算并返回一个新数组
-
forEach没有返回值return是不起作用的,不改变原数组,只用来遍历。适用于需要遍历数组但不需要生成新数组的情况,比如在循环中执行一些操作。
-
终止forEach可以使用try-catch抛出异常并结束循环
-
-
for...in 和 for...of的区别
-
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
null和undefined
console.log(typeof null) // object 表示为“无”对象0
console.log(typeof undefined) // undefined 表示“无”的原始值 NaN
(1)undefined
-
已经声明,未赋值
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())
(2)null
-
手动释放内存
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是对象吗?
-
null不是对象
-
但是typeof null会输出“object”类型,但这是JS存在的一个bug,最初使用32位系统的时候为了性能考虑,使用的是低位存储变量的类型信息,000开头代表是对象,null表示全零,所以会误判为object。