4

基础类:

1、数据类型的转换和比较。 (+2)数据类型转换

+true; //1 ,一元加号会尝试将boolean类型转换为数字类型。 true被转换为1false被转换为0
!"Lydia"; //false
image.png

1、函数传参

对象类型是引用传递

function person(per){
    per.name = 'haha';
    per.age = 3;
    console.log(per)
}
person({name:"www", age: 2})
// {name: "haha", age: 3} 
2、Object.is()和==,===的区别

Object.is方法在===的基础上增加了NaN和NaN是相等的;+0和-0是不相等的
延伸:==隐式转换规则; 运算符的优先级(+1)

+0 === -0   //true
+0 === -'0'   //true
+1 === -'1'   //false
Object.is(+0, -0) //false
2、闭包题。https://segmentfault.com/a/11...
3、事件委托。https://segmentfault.com/a/11...
3、http协议状态码,301和302的区别,304缓存类型,强缓存和协商缓存的区别。etag如何生成的?中间缓存(类似强缓存不发送请求到服务器)
常见的状态码有200,301,302,304,400,404,401,500,502
其中以2开头的代表请求成功,
以3开头的是重定向,其中301是永久重定向,302是临时重定向,
强缓存和协商缓存(+3)<https://segmentfault.com/a/1190000017962411>
4、js运行机制。js运行机制(+2)
5、es6用过哪些。promise的实现原理(+1)【promise实现原理】,all方法(+2)。
Promise.all = function(arr){
    let result = [], count = 0;
    return new Promise(function(resolve, reject){
        for(let item of arr){
            item.then(res=>{
                result[count] = res; 
                count++; 
                if(count === arr.length){
                    resolve(result);
                }
            })
        };  
    });
};
let promise1 = new Promise(function(resolve) {
  resolve(1);
});
let promise2 = new Promise(function(resolve) {
  resolve(2);
});
let promise3 = new Promise(function(resolve) {
  resolve(3);
});
let promiseAll = Promise.all([promise1, promise2, promise3]);
promiseAll.then(function(res) {
  console.log(res);
});

Promise.all = function(arr){
    let result = [], count = 0;
    return new Promise(function(resolve, reject){
        arr.map(item=>{ 
            item.then(res=>{
                result[count] = res;
                count++;
                (count === arr.length) && resolve(result);
            }).catch(err=>{
                result[count] = err;
                count++;
                (count === arr.length) && resolve(result);
            });
        });
    });
};
var p1 = new Promise(function(resolve, reject){reject(1)})
var p2 = new Promise(function(resolve, reject){resolve(2)})
Promise.all([p1, p2]).then(res=>{
    console.log(res)
})
let,const,var声明变量的作用域不同;变量提升;(+1)

   变量的赋值可以分为三个阶段:
 1、创建变量,在内存中开辟空间
 2、初始化变量,将变量初始化为undefined(let和const声明的初始化时不会分配内存,所以会存在暂时性死区)
 3、真正赋值 
  • let,const,var的区别(+2)
    作用域概念不同;变量提升(+1)
  • es6数组常用的api(+1)
  • set,map,
  • 剪头函数和普通函数的区别(+2)
  • map遍历相对于其他遍历方式的优点(+1)
  • class
  • 模板字符串:标签模板
  • await和async的使用(+1)
  • promise.all的实现(+2)
6、isNaN和Number.isNaN的区别

isNaN会有一个转换,能够转换为数字类型的都返回false,
Number.isNaN是严格判断是否为NaN

6、数组的flat扁平化方法。

返回一个新数组对原数组没有影响,默认扁平化一级

6、正则(获取url参数等)。
7、纯函数 (+1)
7、数据类型的判断(+1)
7、instanceof的实现原理(+1)

instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上
MDN说明

function myInstanceof(left, right){
    var left = left.__proto__, right = right.prototype;
    while(true){
        if(left === null)return false;
        if(left === right) return true;
        left = left.__proto__;
    } 
}
7、手写new的实现(+2)
funtion myNew(fn, arg){
    var obj = {};
    obj.__proto__ = fn.prototype;
    fn.apply(obj, arg);
    return obj;
}
7、手写call和apply的实现(+1)
7、defer和async的区别(+1)

如果依赖其他脚本和 DOM 结果,使用 defer
如果与 DOM 和其他脚本依赖不强时,使用 async

7、js监听对象属性的改变具体是怎么实现的,它们各自有什么特点?(+1)
7、移动端适配;rem的使用原理和问题rem的原理及问题(+2);sass,less的优点;移动端几倍图是根据什么来定义的(+1)
7、css布局,flex布局方式(+2)
html部分:
<div class='box'>
    <p>1</p>
    <p>2</p>
    <p>3</p>
</div>
style部分:
.box{
    display: flex;
    justify-content: center;   //水平轴线居中
    aligin-items: center;   //垂直轴线
}
7、实现正方形(+2)
7、五种以上居中方式居中(+1)
7、浏览器如何解析css选择器

image

7、css样式冲突的解决方案,scoped的实现原理
7、css选择器的优先级(+1)

框架应用类:

1、防抖节流(+3)
防抖可应用于阻止重复发送请求,一段时间内重复触发的话则会重新计算时间,只会执行最后一次;
节流是只认第一次的操作,在某一时间段内不管触发多少次,只执行第一次函数的回调;
2、vue双向数据绑定的实现。(+3)
defineProperty——>   proxy的区别
2、nexttick原理。(+1)
2、computed和watch的区别。(+2)
3、vue中key的作用是什么?(+2)
——>diff算法——>重绘和回流(重排)
重绘回流(+1)
3、vue虚拟dom是什么,优缺点(+1)
3、vue生命周期(+1)
3、mvvm模式的理解
3、webpack相关。
  • 优化(配置优化,代码优化)(+2)
  • webpack热更新原理(+1)
  • chunk和baundle的区别(+1)
  • 压缩插件的弊端(+1)
  • 写loader或者plugin
4、axios和ajax的区别,fetch的区别,优势。
5、[跨域方法](+1)(https://juejin.im/post/5c2399...)。
思路:说到跨域先了解同源策略——>常见的跨域场景——>解决方案 
6、组件化

组件可复用性

7、设计模式;
常用的设计模式以及解决了什么问题
8、cdn
8、node的了解
9、vue和react的设计理念,react的简单了解
9、从输入 URL 到页面展示到底发生了什么(+2)——>cdn解析的过程
9、完整的http请求过程;三次握手四次挥手(+3)
9、性能优化【ssr服务端渲染】(+4)
9、性能监控(+1)
9、http协议相关(+1)
9、export和export default,moudle.export的区别(+1)
9、内存泄露(+1)
10、web漏洞(+1)

算法类:

1、数组去重,考虑优化,尽量用最优的算法实现。数组去重方法
for(var i = 0, len = arr.length; i < len; i++){
    for(var j = i+1, lenj = arr.length; j < lenj; j++){
        if(arr[i] == arr[j]){
            arr.splice(j, 1);
            j--;
            lenj--;
            i--;
            len--;
        }
    }
}
var obj = {};
for(var i = 0, len = arr.length; i < len; i++){
    if(!obj[arr[i]]){
        obj[arr[i]] = arr[i];
    } 
} 
console.log(Object.values(obj))
利用indexOf
2、寻找数组中第k大值。
3、有效括号的问题。
4、判断字符串同构。
5、排序,二叉树遍历(中序(+1),后序,前序)。
6、微信红包算法。
7、求字符串中无重复的最长连续子串的长度。
8、千分位实现金额格式化。
8、字符串相加(大数相加)。
8、盛水最多的容器。
8、异步并发控制。
9、冒泡排序,快排。

冒泡排序:每一轮都将相邻的两个元素进行比较;

var arr = [1, 3, 5, 7, 9, 2, 0, 10, 4, 6, 8], flag = true;
for(var i = 0, len = arr.length; i < len; i++){
    flag = false;
    for(var j = 0, lenj = len - 1 - i; j < lenj; j++){
        if(arr[j] > arr[j+1]){
            [arr[j+1], arr[j]] = [arr[j], arr[j+1]];    //数组的解构赋值
            flag = true;
        }
    }
    if(!flag)break;
}

快速排序:
1、选定一个基准元素,将比基准元素小的放在基准元素的左边,比基准元素大的放在基准元素的右边。
2、对左右两边的数组循环进行第一步操作

function quickSort(arr){
    if(arr.length <= 1)return arr;
    var left = [], right = [], pivot = arr.splice(0, 1);
    //`splice()`方法通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。此方法会改变原数组
    arr.map((item, index)=>{
        if(item > pivot){
            right.push(item);
        }else{
            left.push(item);
        }
    })
    return quickSort(left).concat(pivot, quickSort(right));
}

最新面试题链接:https://mp.weixin.qq.com/s/8y...

https://github.com/mqyqingfeng/Blog
https://muyiy.cn/question/


无敌小豆姐
37 声望2 粉丝