JavaScript
序言
整理一些 JavaScript 的相关知识,可能不是太全面,但欢迎补充~~!!!
CodingStartup
-
var、let、const 有什么区别?
var
可以重复证明但会覆盖之前的重名变量、没有作用域特性,但拥有变量提的特性var cool = 1 var cool = 2 ----------------------------------------------------------------------------------- for (var i = 0; i < [1, 2, 3].length; i++) { // ... } console.log(i) // => 3
let
不可以重复声明、不存在变量提升、会产生作用域let cool = 1 let cool = 2 // Error => Identifier 'cool' has already been declared ----------------------------------------------------------------------------------- for (let i = 0; i < [1, 2, 3].length; i++) { // ... } console.log(i) // Error => i is not defined
const
声明一个常量,一经赋值常量的值就不能改变,如果只声明不赋值,也会报错const PI = 3.1415; PI = "我是圆周率" // Error => Assignment to constant variable
如果赋值的是引用数据类型,那么是可以更改其内部的属性或成员的,只要不重新赋值其它的数据类型
const cool = [1, 2, 3] cool.push(4) ----------------------------------------------------------------------------------- cool = {a: 1} // Error => Assignment to constant variable.
-
暂时性死区指的是什么?
ES6规定,
let
、const
命令会使区块形成封闭的作用域,若在声明之前使用变量,就会报错。总之,在代码块内,使用let
声明变量之前,该变量都是不可用的,在这种情况上被称为 ‘‘暂时性死区‘’if (true) { console.log(cool) let cool } // Error => Cannot access 'cool' before initialization
-
const 定义的变量是否能够修改?
一般情况下是不能修改的,如果常量的数据类型是引用类型则可以修改其内部成员和属性,但不能改变数据类型
const cool = {a: 1} cool.b = 2
-
ES6 与 ES5 判断是否完全相等的方法是什么?
判断两个对象是否相等可以使用
Object.is
、恒等于(===)去判断const cool = {a: 1} const so = cool Object.is(cool, so) // => true cool === so // => true
-
ES6 新增方法 Object.assign, 他在作用是什么?
用于对象的合并,将可枚举(
enumerable: true
)属性复制到目标对象中(target
)const cool = {a: 1} Object.assign(cool, {b: 2}) // cool => {a: 1, b: 2}
-
Object.assign 拷贝是深拷贝还是浅拷贝?为什么?
是浅拷贝,因为 Object.assign 拷贝的属性是有限制的,只拷贝源对象的自身属性(不拷贝继承属性),也不拷贝不可枚举的属性(enumerable: false)
-
获取对象的 key 与 value
const cool = { a: 'a', b: 'b' } Object.entries(cool) // => [ ['a', 'a'], ['b', 'b'] ]
-
this 指向都有哪些?
# 函数中的 `this` function cool () { console.log(this) // => Window } # 构造函数中的 `this` function Cool () { console.log(this) // => Cool } new Cool() # 箭头函数中的 `this` const cool = { message: 'Hello World!', coolFn1: () => { console.log(this) // => Window }, coolFn2: function () { console.log(this) // => cool } } cool.coolFn1() cool.coolFn2()
-
箭头函数在this指向是什么?
箭头函数的 this 指向定义时所在的对象
oBtn.onclick = function() { setTimeout(() => { console.log(this) // => oBtn }, 1000) setTimeout(function() { console.log(this) // => Window }, 2000) }
-
数组解构赋值与对象解构赋值的区别?
数组解构赋值属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值
const [a, b] = [1, 2]
对象解构赋值必须与属性同名,才能取到正确的值
const { Cool } = { Cool: 'cool so cool' }
-
两个数的交换
let a = 1; let b = 2; [a, b] = [b, a]
-
ES6 中新增字符串方法有哪些?
includes
检查字符串中是否包含某些字符,返回布尔值,并且支持第二个参数,表示开始搜索的位置,默认是查找所有let str = "abcdefg" console.log(str.includes("f", 0)) // => true
startsWith
用于检索字符串头部是否与指定字符一致console.log(str.startsWith("a")) // => true
endsWith
用于检索字符串末尾是否与指定字符一致console.log(str.endsWith("g")) // => true
repeat
返回一个新字符串,表示将原字符串重复克隆n次let cool = "很酷很酷 "; console.log(msg.repeat(3)) // => 很酷很酷 很酷很酷 很酷很酷
-
ES5 中数组方法都有哪些?
splice
方法用于添加或删除数组中的元素,会改变原始数组const arr = ["cool", "cool so cool"] arr.splice(1, 1) // => ["cool"]
split
将一组字符串分割成字符串数组let str = "border-radius" console.log(str.split("-")) // => ["border", "radius"]
push
向数组末尾添加一个或多个元素,并返回新长度,会改变原数组let arr = [1, 2] arr.push(3) // => [1,2,3]
-
ES6 中新增数组方法都有哪些?
Array.isArray
判断传入的变量是否是数组类型,返回布尔值。let oLi = document.querySelectorAll("ul li"); let arr = [1, 2, 3]; console.log(Array.isArray(oLi)); // false OLi是个伪数组 console.log(Array.isArray(arr)); // true
Array.of
将一组值,转换为数组。let a = 1, b = "哈哈", arr = ["a", "b", "c"], obj = {name: "喜宝"}; console.log(Array.of(a, b, arr, obj)); // 结果 => [1, "哈哈", Array(3), {…}]
Array.from
将伪数组或可迭代的对象转化为数组。let oLi = document.querySelectorAll("ul li"); let elArr = Array.from(oLi); console.log(Array.isArray(elArr)); // true
Array.from接受第二个参数,作用类似
map
方法,可以在原数组取得另一个结果,称之为映射。let arr = [1, 2, 3, 4]; let result = Array.from(arr, function(item, index) { return item + 5; }); console.log(result); // [6, 7, 8, 9]
forEach
循环/迭代数组,跟for循环类似let arr = [{id:1}, {id:2}, {id:3}]; arr.forEach(function(item, index , arr) { // item: 当前index对应数组中的某个元素 // index: 当前循环的下标 // arr: 原数组 });
includes
检索某个数组是否包含给定的值,返回布尔值, 与字符串的includes
方法类似。let arr = [1, 2, 3, 4]; console.log(arr.includes(4)); // true
该方法的第二个参数表示搜索的起始位置。
let arr = [1, 2, 3, 4]; console.log(arr.includes(4, 3)); // true
该方法可以匹配 NaN,而 indexOf 无法匹配。
[NaN].indexOf(NaN); // false [NaN].includes(NaN); // true
flat
多维数组转一维数组let arr = [1,[2,[3,[4]]]]; // 这是一个多维数组 console.log(arr.flat(Infinity)); // [1,2,3,4]
Infinity: 代表的是无限(无穷), 当然如果想转为
n
维数组可以在括号内传入数值
every
依据判断条件,数组内的元素是否全部满足
,返回布尔值。let arr = [1,2,3,4,5,6,7,8,9]; arr.every( item => { return item <= 9; // true 全部满足返回true });
some
根据判断条件,数组内的某一项满足条件
,则返回true, 否则返回false。let arr = [1,2,3,4,5,6,7,8,9]; arr.some( item => { return item <= 8; // true });
filter
过滤数组, 返回一个满足条件的数组。let arr = [1,2,3,4,5,6,7,8,9]; arr.filter( (item, index) => { return item >= 6; // [6,7,8,9] 不改变原数组 });
find
查找数组中符合条件的元素, 若有多个满足的, 则返回第一元素。let arr = [1,2,3,4,5,6,7,8,9]; let result = arr.find( (item, index, arr) => { return item >= 5; }); console.log(result); // 5
findIndex
查找数组中符合条件的元素索引,若有多个符合条件的元素,则返回第一个元素索引。let arr = [1,2,3,4,5,6,7,8,9]; let result = arr.findIndex( (item, index ,arr) => { return item >= 1; }); console.log(result); // 0 代表当前元素在数组中对应的下标
map
映射,起作用是在原数组上获取到另一个结果,并返回一个新的数组,不会改变原数组。
map
方法不会对空数组进行检测。let arr = [300, 200, 100, 56, 90]; let result = arr.map(function(item, index, arr) { return item + item; }); console.log(result); // [600, 400, 200, 112, 180]
上述代码中,在原数组的基础上让每一个元素与自身相加,并返回新数组。
-
如何判断一个对象是对象, 如何判断一个数组是数组?
# 对象 const cool = {} console.log(Object.prototype.toString.call(cool) === '[object Object]') // => true # 数组 const arr = [] Array.isArray(arr) // => true
-
如何将一个对象转换为数组,ES5 ,ES6 的写法分别是什么?
let arrayLike = { '0': 'a', '1': 'b', '2': 'c', length: 3 }; // ES5 var arr1 = [].slice.call(arrayLike); console.log(arr1)// ['a', 'b', 'c'] // ES6 let arr2 = Array.from(arrayLike); console.log(arr2)// ['a', 'b', 'c']
-
如何判断数组是否包含某个给定的值?
const cool = [1, 2] cool.includes(1) // => true
-
filter、map有什么区别
filter
是过滤出满足条件的const cool = [1, 2, 3, 4] cool.filter(item => item >= 2) // => [2, 3, 4]
map
是映射,取得另一种结果const cool = [1, 2, 3, 4] cool.map(item => item * 2) // => [2, 4, 6, 8]
-
some、ervery 有什么区别
every
依据判断条件,数组内的元素是否全部满足
,返回布尔值let arr = [1,2,3,4,5,6,7,8,9]; arr.every( item => { return item <= 9; // true 全部满足返回true });
some
根据判断条件,数组内的某一项满足条件
,则返回true, 否则返回falselet arr = [1,2,3,4,5,6,7,8,9]; arr.some( item => { return item <= 8; // true });
-
reduce 的使用语法,都能实现哪些功能
reduce
方法接收一个参数(sum)作为累加器,数组中的每一个值由左向右依次进行相加或相减等其他运算,并返回计算好的结果let arr = [100, 300, 400, 54, 3]; let result = arr.reduce(function(sum, item, index, arr) { return sum + item; }); console.log(result); // => 853
-
ES6 中的数据结构 Set 的作用
类似于数组,但是是以对象形式承载着所有成员
new Set(["a", "b", "c", "d"]) // => {"a", "b", "c", "d"}
-
ES6 中的数据结构 Map 的作用
Map接受一个数组作为参数,该数组的成员是一个个表示键值对的数组
new Map([ ["a", "1"], ["b", "2"] ]) // => {"a" => "1", "b" => "2"}
-
Promise 的理解
Promise 是异步编程的一种解决方案,简单来说 Promise 是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作例如:Ajax)
new Promise((resolve, reject) => { ajax('', { success: response => { resolve(response) } }) }).then(response => { // ... })
-
Async Await 与 Promise 的区别
Async Await 使得异步代码同步化
async created () { const result = await getData() console.log(result) // => {...} }
Promise 通过 then 的形式去拿到返回的数据
new Promise((resolve, reject) => { ajax('', { success: response => { resolve(response) } }) }).then(response => { // ... })