前端JS相关面试题,排名没有先后只记录
1.Promise.then值穿透
// 例 问最后输出什么?
Promise.resolve('foo')
.then(Promise.resolve('bar'))
.then(function(result){
console.log(result)
})
// 结果 foo
你可能会认为结果是"bar", 其实不然. 结果是"foo".
这个问题记住下面这点:
.then 或者 .catch 的参数期望是函数,传入非函数就会发生值穿透;Promise方法链通过 return 传值,没有 return 就只是相互独立的任务而已
// 依次传值
Promise.resolve('foo')
.then(() => Promise.resolve('bar'))
.then(function(result){
console.log(result)
})
// bar
2. 请写出如下代码的打印结果
function Foo() {
Foo.a = function() {
console.log(1)
}
this.a = function() {
console.log(2)
}
}
// 以上只是 Foo 的构建方法,没有产生实例,此刻也没有执行
Foo.prototype.a = function() {
console.log(3)
}
// 现在在 Foo 上挂载了原型方法 a ,方法输出值为 3
Foo.a = function() {
console.log(4)
}
// 现在在 Foo 上挂载了直接方法 a ,输出值为 4
Foo.a();
// 立刻执行了 Foo 上的 a 方法,也就是刚刚定义的,所以
// # 输出 4
let obj = new Foo();
/* 这里调用了 Foo 的构建方法。Foo 的构建方法主要做了两件事:
1. 将全局的 Foo 上的直接方法 a 替换为一个输出 1 的方法。
2. 在新对象上挂载直接方法 a ,输出值为 2。
*/
obj.a();
// 因为有直接方法 a ,不需要去访问原型链,所以使用的是构建方法里所定义的 this.a,
// # 输出 2
Foo.a();
// 构建方法里已经替换了全局 Foo 上的 a 方法,所以
// # 输出 1
3. 用 JavaScript 写一个函数,输入 int 型,返回整数逆序后的字符串。如:输入整型 1234,返回字符串“4321”。要求必须使用递归函数调用,不能用全局变量,输入函数必须只有一个参数传入,必须返回字符串。
/**
* @case 1234 => '4321'
* @case 1000 => '1'
* @case -1000 => '-1'
* @case -1234 => '-4321'
*
* @param {number} number 传入的数值
*/
function solution(number) {
if (number < 0) {
return `-${solution(Math.abs(number))}`; // 如果是负数取绝对值
}
if (number < 10) {
return `${number}`; // 1位数直接返回
}
return `${number % 10 || ''}${solution(~~(number / 10))}`;
// number % 10 取余数也就是最后一位
// number / 10 减少位数 ~位运算符(按位取反)
// ~~的作用是去掉小数部分,因为位运算的操作值要求是整数,其结果也是整数,所以经过位运算的都会自动变成整数。
}
let n = solution(-123456); // -654321
4. 写出如下代码的打印结果
function changeObjProperty(o) {
o.siteUrl = "http://www.baidu.com"
o = new Object() // 形参 o 的指向发生改变,指向堆内存中一个新的对象
o.siteUrl = "http://www.google.com"
}
let webSite = new Object();
changeObjProperty(webSite);
console.log(webSite.siteUrl); // "http://www.baidu.com"
// 对象作为参数,传递进去的是这个对象的引用地址,o.siteUrl 是给这个对象赋值, o = new Object; 把o指向另一个对象,o.siteUrl 是给这个对象赋值, 不影响webSite 这个变量指向的那个对象, 两个o指向的对象的引用地址不同;
5. React 和 Vue 的 diff 时间复杂度从 O(n^3) 优化到 O(n) ,那么 O(n^3) 和 O(n) 是如何计算出来的?
一两句说不清楚 参考 传统diff、react优化diff、vue优化diff
aooy/blog#2
6.写一个 mySetInterVal(fn, a, b),每次间隔 a,a+b,a+2b,...,a+nb 的时间,然后写一个 myClear,停止上面的 mySetInterVal
function mySetInterVal(fn, a, b){
this.a = a;
this.b = b;
this.n = 0;
this.timeoutID= -1;
this.start = () => {
this.timeoutID = setTimeout(()=>{
fn();
this.n++;
this.start();
console.log(this.a + this.n*this.b);
}, this.a + this.n*this.b)
}
this.clear = () => {
clearTimeout(this.timeoutID);
this.n = 0;
}
}
let myFunc = new mySetInterVal(() => {console.log('123')},1000, 2000 );
myFunc.start();
myFunc.clear();
7.将数组扁平化并去除其中重复数据,最终得到一个升序且不重复的数组
已知如下数组:
var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10];
编写一个程序将数组扁平化去并除其中重复部分数据,最终得到一个升序且不重复的数组
Array.from(new Set(arr.flat(Infinity))).sort((a,b)=>{ return a-b})
8. 数组扁平化 5 种方法
- toString & split
arr.toString().split(',')
- ES6 flat()
arr.flat(Infinity)
- ES6 扩展运算符 ...
const flatten = (arr) => {
while (arr.some(item => Array.isArray(item))) {
arr = [].concat(...arr) // 给原数组重新赋值
}
return arr
}
- reduce() 方法
const flatten = (arr) => {
return arr.reduce((pre, next) => {
return pre.concat(Array.isArray(next) ? flatten(next) : next);
}, [])
}
- 递归
const flatten = (arr) => {
let res = []
arr.forEach(item => {
if (Array.isArray(item)) {
res = res.concat(flatten(item))
} else {
res.push(item)
}
})
return res
}
9. 数组去重
- 利用ES6中的 Set 方法去重
注:Set为ES6新增的一个对象,允许存储任何类型(原始值或引用值)的唯一值
function unique(arr) {
return Array.from(new Set(arr))
}
- 使用双重for循环,再利用数组的splice方法去重(ES5常用)
function unique(arr) {
for(let i = 0, len = arr.length; i < len; i++) {
for(let j = i+1, len = arr.length; j < len; j++) {
if(arr[i] === arr[j]) {
arr.splice(j, 1);
j--; // 每删除一个数就减一
len--; // j减少len也相应减少(减少循环,节省性能)
}
}
}
return arr;
}
- 利用数组的indexOf方法去重
注:array.indexOf(item,statt) 返回数组中某个指定的元素的位置,没有则返回-1
function unique(arr){
var arr1 = []; // 新建一个数组来存放arr中的值
for(var i=0,len=arr.length;i<len;i++){
if(arr1.indexOf(arr[i]) === -1){
arr1.push(arr[i]);
}
}
return arr1;
}
- 利用数组的sort方法去重(相邻元素对比法)
注:array.sort( function ) 参数必须是函数,可选,默认升序
function unique(arr) {
arr = arr.sort();
let arr1 = [arr[0]];
for(let i = 1, len = arr.length; i<len; i++){
if(arr[i] !== arr[i-1]) {
arr1.push(arr[i])
}
}
return arr1
}
- 利用数组的includes去重
注:arr.includes(指定元素(必填),指定索引值(可选,默认值为0) ),有值返回true,没有则返回false
function unique(arr){
var arr1 = []; // 新建一个数组来存放arr中的值
for(var i=0,len=arr.length;i<len;i++){
if(!arr1.includes(arr[i])){ // 检索arr1中是否包含有arr中的值
arr1.push(arr[i]);
}
}
return arr1;
}
- 利用数组的filter方法去重
注:filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素,array.filter(function(currentValue,index,arr), thisValue). currentValue:当前元素的值(必选参数)、index:当前元素的索引值(可选)、arr:当前元素属于的数组对象(可选)、thisValue:对象作为该执行回调时使用,传递给函数,用作 “this” 的值,默认undefined(可选)
function unique(arr) {
return arr.filter((item, index) => {
return arr.indexOf(item, 0) === index;
})
}
- 利用函数递归去重
function unique(arr) {
let arr1 = arr;
let len = arr1.length;
arr1.sort((a, b) => a - b);
function loop(index) {
if(index>=1){
if(arr1[index] === arr1[index-1]) {
arr1.splice(index, 1)
}
loop(index -1 )
}
}
loop(len - 1);
return arr1
}
- 利用ES6中的Map方法去重
创建一个空Map数据结构,遍历需要去重的数组,把数组的每一个元素作为key存到Map中。由于Map中不会出现相同的key值,所以最终得到的就是去重后的结果。
function unique(arr) {
let map = new Map();
let arr1 = []
for (let i = 0, len = arr.length; i < len; i++) {
if (map.has(arr[i])) { // 判断是否存在该key值
map.set(arr[i], true);
} else {
map.set(arr[i], false);
arr1.push(arr[i]);
}
}
return arr1;
}
网友评论