前端刷题过程中遇到的重点题记录

前言此篇包括但不仅限于对前一篇博客知识点的补充1.手写深度比较,模拟lodash isEqual关于深度比较的理解:如果obj1和obj2的属性、值全部相等,但是令他们 = = =的时候,还是返回false,因为他们的地址不同,深度比较就是能对两个地址不同,值相同的对象进行比较,返回true。function isObject(obj){ return typeof obj === 'object' && obj !== null;}function isEqual(o
摘要由CSDN通过智能技术生成

前言

我找工作期间遇到的所有前端相关的重点问题,可以说是想找到一个还不错的工作的话,至少以下所有问题都需要会

1.手写深度比较,模拟lodash isEqual

关于深度比较的理解:如果obj1和obj2的属性、值全部相等,但是令他们 = = =的时候,还是返回false,因为他们的地址不同,深度比较就是能对两个地址不同,值相同的对象进行比较,返回true。

function isObject(obj){
   
    return typeof obj === 'object' && obj !== null;
}

function isEqual(obj1,obj2){
   
    if(!isObject(obj1)||!isObject(obj2)){
   
        return obj1 === obj2
    }
    if(obj1 === obj2)  return true;
    const objkey1 = Object.keys(obj1);
    const objkey2 = Object.keys(obj2);
    if(objkey1.length !== objkey2.length) return false;
    for(let key in obj1){
   
        const re  = isEqual(obj1[key],obj2[key]);
        if(!re){
   
            return false
        }
    }
    return true;
}

2.数组的pop push unshift shift

pop:删除末尾元素,返回删除的元素
shift:删除首个元素,返回删除的元素
push:末尾添加元素,返回数组长度
unshift:首位添加元素,返回数组长度

纯函数:不改变源数组(没有副作用),返回一个数组。以下是一些纯函数:
some every

const arr = [10,20,30,40];

const arr1 = arr.concat([50,60,70]);//合并数组
const arr2 = arr.map(num => num*10);//对数组中的每个数执行一个新函数,然后返回新数组
const arr3 = arr.filter(num => num >25);//对数组中的每个数执行新函数,返回值为true的数组成新数组
const arr4 = arr.slice(2,4);//切割数组,返回切下来的部分

一些非纯函数:
pop push unshift shift forEach(如果数组的值全是基本数据类型的话就是纯函数,如果数组中还有引用类型的话,那就不是纯函数)
reverse
reduce

3.数组slice和splice的区别

const arr = [10,20,30,40,50];

const arr1 = arr.slice();//不传参类似于深拷贝
const arr2 = arr.slice(1,4);
const arr3 = arr.slice(2);//截取数组下标为2的一直到最后一个
const arr4 = arr.slice(-2); //截取最后两个

//splice 非纯函数
const spliceRes = arr.splice(1,2,'a','b','c');
const spliceRes2 = arr.splice(1,2)
console.log(spliceRes,arr);//[20,30] [10,'a','b','c',40,50]
console.log(spliceRes2);//返回剪掉的部分

4.[10,20,30].map(parseInt)的返回值

const res = [10,20,30].map(parseInt);
console.log(res);//[10,NaN,NaN]

// 等价于
[10,20,30].map((n, index) =>{
   
    return parseInt(n, index)
})

parseInt的第二个参数如果是0,则以10为基数来解析,如果以0x开头则以16为基数,如果小于2或者大于36,返回NaN.

5.http的八种请求(ajax请求get和post的区别)

在这里插入图片描述
1、OPTIONS
返回服务器针对特定资源所支持的HTTP请求方法,也可以利用向web服务器发送‘*’的请求来测试服务器的功能性
2、HEAD
向服务器索与GET请求相一致的响应,只不过响应体将不会被返回。这一方法可以再不必传输整个响应内容的情况下,就可以获取包含在响应小消息头中的元信息。
3、GET
向特定的资源发出请求。注意:GET方法不应当被用于产生“副作用”的操作中,例如在Web Application中,其中一个原因是GET可能会被网络蜘蛛等随意访问。Loadrunner中对应get请求函数:web_link和web_url
4、POST
向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。 Loadrunner中对应POST请求函数:web_submit_data,web_submit_form
5、PUT
向指定资源位置上传其最新内容
6、DELETE
请求服务器删除Request-URL所标识的资源
7、TRACE
回显服务器收到的请求,主要用于测试或诊断
8、CONNECT
HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
注意:
1)方法名称是区分大小写的,当某个请求所针对的资源不支持对应的请求方法的时候,服务器应当返回状态码405(Mothod Not Allowed);当服务器不认识或者不支持对应的请求方法时,应返回状态码501(Not Implemented)。
2)HTTP服务器至少应该实现GET和HEAD/POST方法,其他方法都是可选的,此外除上述方法,特定的HTTP服务器支持扩展自定义的

GET和POST的区别
1.get是从服务器上获取数据,post是向服务器传送数据。

2.get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到。post是通过HTTPpost机制,将表单内各个字段与其内容放置在HTML HEADER内一起传送到ACTION属性所指的URL地址。用户看不到这个过程。

3.对于get方式,服务器端用Request.QueryString获取变量的值,对于post方式,服务器端用Request.Form获取提交的数据。

4.get传送的数据量较小,不能大于2KB。post传送的数据量较大,一般被默认为不受限制。但理论上,IIS4中最大量为80KB,IIS5中为100KB。(这里有看到其他文章介绍get和post的传送数据大小跟各个浏览器、操作系统以及服务器的限制有关)

5.get安全性非常低,post安全性较高。

6.函数call和apply的区别

fn.call(this, p1, p2, p3)
fn.apply(this, arguments)
就是传参方式不同

7.new Object()和Object.create()的区别

{}等同于 new Object(),原型是Object.prototype
object.create(null)没有原型
object.create({…})可以指定原型,传入的参数即为新创建的空对象的原型

8.判断字符串以字母开头,后面字母数字下划线,长度6-30(一些简单的正则表达式)

//邮政编码

/\d{
   6}/ //\d匹配数字

//小写英文字母

/^[a-z]+$/

//英文字母
/^[a-zA-Z]+$/

//日期格式
/^\d{
   4}-\d{
   1,2}-\d{
   1,2}$/

//用户名(\w 在正则表达式中表示一个“字”(数字,字符,下划线) 
/^[a-zA-Z]\w{
   5,17}$/ 

//简单的IP地址匹配
/\d+\.\d+\.\d+\.\d+/

//匹配电话号码
/^1[3456789]\d{
   9}$/

//匹配科学计数法
str.replace(/\B(?=((\d{3})+)$)/g,',')

// aaaa-aaa-bbb转为aaaaAaaBbb
var str2 = str.replace(/-\b\w/g,function(th){
   
    th = th.slice(1);
    return th.toUpperCase();
})

9.手写字符串trim保证浏览器兼容性

trim就是用于删除字符串两端的空白

 String.prototype.trim = function(){
   
          return this.replace(/^\s+/,'').replace(/\s+$/,'');
      }

10.如何捕获JS中的异常

//手动捕获
try{
   
//todo
} catch(ex){
   
console.error(ex) //手动捕获 catch
}finally {
   
// todo
}
//自动捕获
window.onerror = function(message, source, lineNum, colNum, error)
//缺点:第一,对跨域的JS,如CDN,不会有详细的报错信息
    // 第二,对于压缩的js,还要配合 sourceMap 反查到未压缩的代码的行、列

11.获取当前页面url参数

1.传统方式,查找location.search
2.新API,URLSearchParams

//传统方式
function  query(name){
   
    const search = location.search.substr(1); //类似 array.slice,用于去掉问号
    const reg = new RegExp('(^|&)${name}=([^&]*)(&|$)','i')
    const res = search.match(reg);
    if(res == null){
   
        return null
    }
    return res[2]
}
query('a')

//URLSearchParams
function query(name){
   
    const search = location.search
    const p = new URLSearchParams(search);
    return p.get(name);
}

console.log(query('a'))

12.手写flatern考虑多层级

function flat(arr){
   
    const isDeep = arr.some(item => item instanceof Array)
    if(!isDeep){
   
        return arr
    }

    const res = Array.prototype.concat.apply([],arr);
    //arr作为apply方法的第二个参数,本身是一个数组,数组中的每一个元素(还是数组,即二维数组的第二维)会被作为参数依次传入到concat中,效果等同于[].concat(1, 2, 3, [4, 5, 6], 7, 8, [9, 10])。利用apply方法,我们将单重循环优化为了一行代码
    return flat(res)
}

13.数组去重

//传统方式
function unique(arr){
   
    const res = [];
    arr.forEach(item => {
   
        if(res.indexOf(item)<0){
   
            res.push(item)
        }
    });
    return res
}

//使用set的方式(set无序,不能重复)
function unique(){
   
    const set  = new Set(arr);
    return [...set];
}

14.介绍RAF requetAnimationFrame

要想动画流畅。更新频率要60帧/s,即16.67ms更新一次视图
setTimeout 要手动控制频率,而RAF浏览器会自动控制
后台标签或隐藏iframe中,RAF会暂停
,而setTimeout依然执行

//3s把宽度从 100px 变为 640px, 即增加540px
//60帧/s, 3s 180帧  一帧变化3px

//setTimeout
let curWidth = 100,
    maxWidth = 640,
    div1 = document.getElementById('div1');

function animate(){
   
    curWidth = curWidth + 3;
    div1.style.width = curWidth + 'px';
    if(curWidth<maxWidth){
   
        setTimeout(animate,16.7) //时间需要自己控制
    }
}
animate()

//RAF
function animate(){
   
    curWidth = curWidth + 3;
    div1.style.width = curWidth + 'px';
    if(curWidth<maxWidth){
   
        window.requestAnimationFrame(animate);//时间不用自己控制
    }
}
animate()

15.CSS实现动画

1.transition实现
transition的速度属性:linear(匀速)、ease(从慢到快再变慢)、ease-in(慢开始)、ease-out(慢结束)


                
  • 5
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值