移动应用开发实验室web组js第一次考核
请简述var,let,const的区别
var
- var存在变量提升、暂时性死区
- 可以重复赋值
let
- let不存在变量提升、暂时性死区
- 块级作用域
- 可以重复赋值
const
- const不存在变量提升、暂时性死区
- 声明时必须定义值
- 块级作用域
解释垃圾回收机制,垃圾回收的方式
垃圾回收机制
如果一个对象不再被程序中的任何部分所引用,那么这个对象就可以被回收。垃圾回收器会定期检查并回收这些不再被使用的内存空间
垃圾回收的方式
- 标记清除
- 标记整理
- 分代收集
- 引用计数
以下代码的输出是什么
var tmp=new Date()
function fn(){console.log(tmp);if(false){var tmp='hello world'}
}
fn()
undefined
由于tmp只被定义了没被赋值,而if操作不会被执行
this的指向
var name = "window";
var person = {name: "person",sayName: function () {console.log(this.name);//person},hello: () => console.log(this.name)//window
};
function sayName() {var sss = person.sayName;sss();//windowperson.sayName();//person(person.sayName)();//window,person.sayName 被引用并立即调用,但同样作为普通函数调用,而不是作为对象的方法(b = person.sayName)();//window,同上种情况类似person.hello()//window,箭头函数的this指向上下文的this值
}
sayName();
实现数组扁平化
let arr = [1, [2, [3, 4, 5]]]
方法1:使用递归
递归是一种直接且易于理解的方法,特别是当数组的嵌套层次未知时。
function flattenArray(arr) { let result = []; arr.forEach(item => { if (Array.isArray(item)) { result = result.concat(flattenArray(item)); } else { result.push(item); } }); return result;
} let arr = [1, [2, [3, 4, 5]]];
console.log(flattenArray(arr)); // 输出: [1, 2, 3, 4, 5]
方法2:使用扩展运算符(ES6+)
这种方法适用于嵌套层数较少且已知的情况,或者与递归结合使用。
function flattenArray(arr) { while (arr.some(item => Array.isArray(item))) { arr = [].concat(...arr); } return arr;
} let arr = [1, [2, [3, 4, 5]]];
console.log(flattenArray(arr)); // 输出: [1, 2, 3, 4, 5]
方法3:使用栈(迭代方式)
迭代方式使用栈来模拟递归过程,对于深度较大的数组来说,可以避免递归可能导致的栈溢出问题。
function flattenArray(arr) { let stack = [...arr]; let res = []; while (stack.length) { // pop 出 stack 的最后一个元素 let next = stack.pop(); if (Array.isArray(next)) { // 如果是数组,则展开后并入 stack stack.push(...next); } else { // 否则,添加到结果数组中 res.push(next); } } // 注意:因为是从 stack 尾部取元素,所以结果需要反转 return res.reverse();
}
let arr = [1, [2, [3, 4, 5]]];
console.log(flattenArray(arr)); // 输出: [1, 2, 3, 4, 5]
方法4:使用flat()方法(ES2019+)
如果你使用的是较新的JavaScript环境(如ES2019及以上),则可以直接使用数组的flat()方法来实现扁平化
let arr = [1, [2, [3, 4, 5]]];
// Infinity 表示无论多少层嵌套都扁平化
console.log(arr.flat(Infinity)); // 输出: [1, 2, 3, 4, 5]
flat()方法接受一个参数,表示要展开的嵌套层数。如果参数是Infinity,则表示无论嵌套了多少层,都将展开成一层。
实现数组去重
const array = [1, 2, 3, 5, 1, 5, 9, 1, 2, 8];
方法1:使用Set
Set是ES6中引入的一种新的数据结构,它类似于数组,但是成员的值都是唯一的,没有重复的值。利用这个特性,我们可以很容易地去除数组中的重复元素
const array = [1, 2, 3, 5, 1, 5, 9, 1, 2, 8];
const uniqueArray = [...new Set(array)];
console.log(uniqueArray); // 输出: [1, 2, 3, 5, 9, 8]
方法2:使用filter()和indexOf()
filter()方法创建一个新数组,其包含通过所提供函数实现的测试的所有元素。而indexOf()方法返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回-1。利用这个特性,我们可以检查元素是否已经在结果数组中
const array = [1, 2, 3, 5, 1, 5, 9, 1, 2, 8];
const uniqueArray = array.filter((item, index, self) => { return self.indexOf(item) === index;
});
console.log(uniqueArray); // 输出: [1, 2, 3, 5, 9, 8]
方法3:使用Map对象
Map对象保存键值对,并且一个键可以映射到最多一个值。利用这个特性,我们可以将数组中的元素作为键存储到Map对象中,然后获取Map对象的键组成一个新数组,从而实现去重
const array = [1, 2, 3, 5, 1, 5, 9, 1, 2, 8];
const map = new Map();
array.forEach(item => map.set(item, true));
const uniqueArray = Array.from(map.keys());
console.log(uniqueArray); // 输出: [1, 2, 3, 5, 9, 8]
方法4:使用reduce()
reduce()方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。这个方法也可以用来去重
const array = [1, 2, 3, 5, 1, 5, 9, 1, 2, 8];
const uniqueArray = array.reduce((acc, current) => { if (acc.indexOf(current) === -1) acc.push(current); return acc;
}, []);
console.log(uniqueArray); // 输出: [1, 2, 3, 5, 9, 8]
JS中的基本类型
number数字型
string字符串型
boolean布尔型 let isCool = true
undefined未定义型,没赋值,不确定是什么类型
null空类型
bigInt(范围比正常的number大)
symbol唯一的值
讲一下JS的事件流
事件流描述了当事件发生时,事件如何传播通过DOM的层次结构。主要有两种事件流模型被广泛认知:事件冒泡和事件捕获
事件冒泡
当事件在DOM的某个元素上被触发时,这个事件会沿着DOM树向上传播,依次触发祖先元素上的同名事件处理函数,直到达到最顶层的元素或者某个祖先元素阻止了事件的进一步传播
事件捕获
与事件冒泡相反,事件捕获是事件从DOM树的最顶层开始向下传播到目标元素的过程。这意味着,在事件到达目标元素之前,它会先触发目标元素的所有祖先元素上的事件处理函数
事件流
首先进行事件捕获,然后是目标元素本身的事件处理,最后是事件冒泡