请简述var,let,const的区别
var
- 声明的是变量
- 存在变量提升和重复声明
- 存在暂时性死区
- 不用设置初始值
- 具有函数作用域或全局作用域
let
- 声明的是变量
- 具有块级作用域
- 不用设置初始值
- 不存在变量提升、重复声明、暂时性死区
const
- 声明的是常量
- 声明一个只读的常量
- 必须设置初始值
- 不存在变量提升、重复声明、暂时性死区
解释垃圾回收机制,垃圾回收的方式
解释:垃圾回收是指自动释放不再使用的内存。程序在运行时会动态分配内存,但并不是所有被分配的内存都会一直被使用。垃圾回收机制的任务就是识别那些不再被使用的内存,并将其释放回系统,以便其他进程可以使用
方式:标记清除算法,引用计数算法
以下代码的输出是什么
var tmp=new Date()
function fn(){
console.log(tmp);
if(false){
var tmp='hello world'
}
}
fn()
结果:undefined
解析:var存在变量提升,内层定义的tmp由于变量提升覆盖了外层定义的tmp,实际的执行如下
var tmp=new Date()
function fn(){var tmp;
console.log(tmp);
if(false){
var tmp='hello world'
}
}
fn()
this的指向
var name = "window";
var person = {
name: "person",
sayName: function () {
console.log(this.name);
},
hello: () => console.log(this.name)
};
function sayName() {
var sss = person.sayName;
sss();//window
person.sayName();//person
(person.sayName)();//window
(b = person.sayName)();//window
person.hello()//window
}
sayName();
解析
- sss(): 默认绑定, 是独立函数调用, this指向window
- person.sayName(): 隐式绑定, this指向发起调用的对象, 因此this指向person
- (person.sayName)(): 隐式绑定, 不要被小括号迷惑, "."的优先级很高的, 依然是隐式绑定, this指向发起调用的对象person
- (b = person.sayName)(): 默认绑定, 这是规则之外的间接函数引用, 赋值语句最终返回一个函数, 函数后面跟小括号就是默认绑定, 独立函数调用, 因此this指向windod
- person.hello():这里使用了箭头函数来定义
hello
方法。箭头函数不会创建自己的this
绑定,而是从外围作用域继承,外围的this是window,因此this指向window
实现数组的扁平化
let arr = [1, [2, [3, 4, 5]]]
方法一:递归
通过循环递归的方式,一项一项地去遍历数组,如果每一项还是一个数组,那么就继续往下遍历,实现方式,如下所示:
var array = [1, [2, [3, 4, 5]]];
function flatDeep(arr){
let result = [];
for(let i = 0; i < arr.length; i++) {
if(Array.isArray(arr[i])){
result = result.concat(flatDeep(arr[i]))
} else {
result.push(arr[i])
}
}
return result;
}
console.log(flatDeep(array));
方法二:用reduce函数
使用reduce方法累加效果,实现思路跟常规的递归方法有些相似,代码如下:
var array = [1, [2, [3, 4, 5]]];
function flatDeep(arr){
return arr.reduce(function(pre,next){
if(Array.isArray(next)){
return pre.concat(flatDeep(next))
} else {
return pre.concat(next)
}
}, [])
}
方法三:用ES6的flat方法
var array = [1, [2, [3, 4, 5]]];
function flatDeep(arr) {
return arr.flat(Infinity)
}
console.log(flatDeep(array));
实现数组去重
const array = [1, 2, 3, 5, 1, 5, 9, 1, 2, 8];
方法一:利用 ES6 Set 去重(ES6 中最常用)
function unique (arr) {
return Array.from(new Set(arr))
}
方法二:利用循环和splick
function unique(arr){
for(var i=0; i<arr.length; i++){
for(var j=i+1; j<arr.length; j++){
if(arr[i]==arr[j]){ //第一个等同于第二个,splice方法删除第二个
arr.splice(j,1);
j--;
}
}
}
return arr;
}
JS中的基本类型
Number、undefined、Array、bigInt、String、null、symbol、boolean
讲一下JS的事件流
JS的事件流分成三个阶段事件捕获阶段、目标阶段、冒泡阶段
首先是事件捕获阶段:从父到子的进行到目标阶段,捕获阶段的任务就是建立这个事件传递路线,以便后面冒泡阶段顺着这条路
然后是目标阶段:事件捕获到目标进入目标阶段
最后是冒泡阶段:从子到父进行冒泡