美文网首页
前端面试题之js篇(以及网络协议、储存)

前端面试题之js篇(以及网络协议、储存)

作者: Kyriez7 | 来源:发表于2022-03-02 11:26 被阅读0次

    JS面试题

    • js基本类型和引用类型
    • 说说写JavaScript的基本规范?
    • js如何判断一个对象是数组
    • 怎么判断两个对象相等
    • "=="和"==="的不同
    • js对数组操作的常用方法有哪些?
    • split() join() 的区别
    • js 拷贝
    • 原型和原型链
    • 什么是闭包
    • 事件循环机制(event loop)
    • require和import区别
    • 怎么理解js中的内存泄露
    • js延迟加载的方式有哪些?
    • 如何阻止事件冒泡
    • 浅谈setTimeout 和 setInterval
    • JavaScript作用域链
    • Ajax使用
    • 谈谈this的理解
    • 什么是window对象? 什么是document对象?
    • null,undefined的区别?
    • new操作符具体干了什么呢?
    • 同步和异步的区别?
    • 回流与重绘
    • DOM操作
    • 数组对象有哪些原生方法,列举一下
    • 哪些操作会造成内存泄漏
    • 请描述一下cookie,sessionStorage和localStorage的区别
    • http状态码有那些?分别代表是什么意思?列举2-3个熟悉的状态码
    • 一个 http 请求由什么组成?
    • http 协议的 三次握手/四次挥手,可以描述一下吗?
    • ajax请求的时候get 和post方式的区别?
    • 什么是防抖和节流?有什么区别?如何实现?

    js面试题解析

    js基本类型和引用类型

    • null(空)
    • undefined(未声明)
    • number(数字)
    • string(字符串)
    • object(对象)
    • boolean(布尔值)
    • symbol(符号,es6新增)
      基本数据类型:Undefined、Null、Boolean、String、Number、Symbol (es6)。
      引用类型:Object。Object可以细分为:Object 类型、Array 类型、Date 类型、RegExp 类型、Function 类型

    说说写JavaScript的基本规范?

    • 不要在同一行声明多个变量
    • 使用 ===或!==来比较true/false或者数值
    • switch必须带有default分支
    • 函数应该有返回值
    • for if else 必须使用大括号
    • 语句结束加分号
    • 命名要有意义,使用驼峰命名法

    js如何判断一个对象是数组

    1.typeof操作符

    • 利用typeof除了array和null判断为object外,其他的都可以正常判断

    2.instanceof操作符

    var arr = [1,2,3,1];
    console.log(arr instanceof Array); // true
    
    var fun = function(){};
    console.log(fun instanceof Function); // true
    

    3.对象的constructor 属性

    var arr = [1,2,3,1];
    console.log(arr.constructor === Array); // true
    var fun = function(){};
    console.log(arr.constructor === Function); // true
    

    4.使用 Object.prototype.toString 来判断是否是数组

    Object.prototype.toString.call( [] ) === ``'[object Array]'` `// true` 
    
    Object.prototype.toString.call( ``function``(){} ) === ``'[object Function]'` `// true
    

    这里使用call来使 toString 中 this 指向 obj。进而完成判断

    5.Array.isArray()

    Array.isArray([])  ``// true
    

    6.使用 原型链 来完成判断

    [].__proto__ === Array.prototype ``// true` `var` `fun = ``function``(){}``fun.__proto__ === Function.prototype ``// true
    

    怎么判断两个对象相等

    JSON.stringify(obj)==JSON.stringify(obj); //true

    image.png

    "=="和"==="的不同

    • 前者会自动转换类型,再判断是否相等
      具体如下:
      一、首先看双等号前后有没有NaN,如果存在NaN,一律返回false。
      二、再看双等号前后有没有布尔,有布尔就将布尔转换为数字(false是0,true是1)
      三、接着看双等号前后有没有字符串, 有三种情况:
      1、对方是对象,对象使用toString()或者valueOf()进行转换;
      2、对方是数字,字符串转数字;(前面已经举例)
      3、对方是字符串,直接比较;
      4、其他返回false
      四、如果是数字,对方是对象,对象取valueOf()或者toString()进行比较, 其他一律返回false
      五、null, undefined不会进行类型转换, 但它们俩相等
    • 后者不会自动类型转换,直接去比较

    js对数组操作的常用方法有哪些?

    1、shift():删除原数组第一项,并返回删除元素的值;如果数组为空则返回undefine。这里是0
    2、unshift(3,4):把参数加载数组的前面,并返回新数组长度。现在list:中是3,4,0,1,2
    3、pop():删除最后一项,并返回删除元素的值;如果数组为空则返回undefine。这里是2.
    4、push(3):将参数加载到数组的最后,并返回新数组长度,现在List中时:0,1,2,3
    5、concat(3,4):把两个数组拼接起来,返回合并后的新数组,原数组木变。
    6、splice(start,deleteCount,val1,val2,...):从start位置开始删除deleteCount项,并从该位置起插入val1,val2,...
    7、reverse:并返回翻转后的原数组,原数组翻转了
    8、sort(orderfunction):按指定的参数对数组进行排序 var a = [1,2,3,4,5]; var b = a.sort(); //a:[1,2,3,4,5] b:[1,2,3,4,5]
    9、slice(start,end):返回从原数组中指定开始下标到结束下标之间的项组成的新数组,原数组木变,索引从0开始
    10、join 将数组转换成字符串并返回字符串.将数组中所有元素以参数作为分隔符放入一个字符,原数组木变
    11、indexOf 数组元素索引,并返回元素索引,不存在返回-1,索引从0开始
    改变原数组的:
    shift,unshift,pop,push,reverse,sort,splice
    不改变原数组的:
    concat,join,slice:slice(start,end),map,filter,some,every

    split() join() 的区别

    前者是将字符串切割成数组的形式,后者是将数组转换成字符串

    js 拷贝

    分为深拷贝和浅拷贝。

    • 浅拷贝: 只对基本数据类型进行拷贝,方法有:Object.assign() 、es6的结构赋值、数组的slice、concat方法、展开运算符、Array.from。
    • 深拷贝:对所有数据类型进行真正的拷贝,方法有:利用JSON.stringify() 和JSON.parse()、利用递归实现。

    原型和原型链

    • 在JavaScript中万物都是对象,对象和对象之间也有关系,并不是孤立存在的。对象之间的继承关系,在JavaScript中是通过prototype对象指向父类对象,直到指向Object对象为止,这样就形成了一个原型指向的链条,专业术语称之为原型链。
    • 原型也是一个对象,通过原型可以实现对象的属性继承,JavaScript的对象中都包含了一个”[[Prototype]]”内部属性,这个属性所对应的就是该对象的原型。

    什么是闭包

    要了解闭包,要先了解什么是作用域(作用域就是变量与函数的可访问范围: 任何地方都能访问到的对象拥有全局作用域,局部作用域一般只在固定的代码片段内可访问到,最常见的例如函数内部),函数内部可以直接读取全局变量,但是函数外部是无法读取函数内的局部变量,那么如何可以在外部读取到函数内部的变量,可以通过函数内部的函数实现,在这个内部函数中去访问函数内部的变量,并将其返回,这就形成了闭包,即能够读取其他函数内部变量的函数。闭包就是能够读取其他函数内部变量的函数

    function test() {
          const z = 1
          return function() {
            console.log('z',z)
          }
        }
        const fn = test()
        const z = 2
        fn()
        // 'z', 1
        返回的是函数位置指向最靠近的上一级的z的值
    

    事件循环机制(event loop)

    • js代码执行时,先按代码顺序将同步任务压入主执行栈中执行
    • 遇到异步任务则先将异步任务压入对应的任务队列中(宏队列或微队列)
    • 同步任务执行完毕后,查看微队列,将微任务一一取出进入主执行栈中执行
    • 微任务队列清空后,再查看宏队列,只取出第一个宏任务执行,执行完一个宏任务后,回到第三步的操作 这个过程是循环不断的,所以整个的这种运行机制又称为Event Loop(事件循环)

    require和import区别

    • import和require都是被模块化使用
    • require是运行时调用,所以可以随处引入
    • import是编译时调用,必须放在文件开头引入,目前部分浏览器不支持,需要用babel把es6转成es5再执行说

    怎么理解js中的内存泄露

    定义:程序不需要的内存,由于某些原因其不会返回到操作系统或者可用内存池中。 内存泄露会导致(运行缓慢 ,高延迟,崩溃)的问题
    常见的导致内存泄露的原因有:

    • 意外的全局变量
    • 被遗忘的计时器或回调函数
    • 脱离文档的DOM的引用
    • 闭包

    js延迟加载的方式有哪些?

    defer和async、动态创建DOM方式(创建script,插入到DOM中,加载完毕后callBack)、按需异步载入js

    • 没有 defer 或 async,浏览器会立即加载并执行指定的脚本,“立即”指的是在渲染该 script 标签之下的文档元素之前,也就是说不等待后续载入的文档元素,读到就加载并执行。
    • 有 async,加载和渲染后续文档元素的过程将和 script.js 的加载与执行并行进行(异步)。
    • 有 defer,加载后续文档元素的过程将和 script.js 的加载并行进行(异步),但是 script.js 的执行要在所有元素解析完成之后,DOMContentLoaded 事件触发之前完成。

    如何阻止事件冒泡

    ie:阻止冒泡ev.cancelBubble = true;非IE ev.stopPropagation();
    如何阻止默认事件
    (1)return false;(2) ev.preventDefault();

    浅谈setTimeout 和 setInterval

    • 前者是在一定时间过后将函数添加至执行队列,执行时间=延迟时间+之前函数代码执行时间+执行函数时间。
    • 后者是不管前一次是否执行完毕,每隔一定时间重复执行,用于精准执行互相没有影响的重复操作。

    Javascript作用链域

    作用域链的原理和原型链很类似,如果这个变量在自己的作用域中没有,那么它会寻找父级的,直到最顶层。
    注意:JS没有块级作用域,若要形成块级作用域,可通过(function(){})();立即执行的形式实现。

    Ajax使用

    全称 : Asynchronous Javascript And XML
    所谓异步,就是向服务器发送请求的时候,我们不必等待结果,而是可以同时做其他的事情,等到有了结果它自己会根据设定进行后续操作,与此同时,页面是不会发生整页刷新的,提高了用户体验。

    创建Ajax的过程:

    • 创建XMLHttpRequest对象(异步调用对象)
    var xhr = new XMLHttpRequest();
    
    • 创建新的Http请求(方法、URL、是否异步)
    xhr.open(‘get’,’example.php’,false);
    
    • 设置响应HTTP请求状态变化的函数。
      onreadystatechange事件中readyState属性等于4。响应的HTTP状态为200(OK)或者304(Not Modified)。
    • 发送http请求
    xhr.send(data);
    
    • 获取异步调用返回的数据
      注意:
      1 页面初次加载时,尽量在web服务器一次性输出所有相关的数据,只在页面加载完成之后,用户进行操作时采用ajax进行交互。
      2 同步ajax在IE上会产生页面假死的问题。所以建议采用异步ajax。
      3 尽量减少ajax请求次数
      4 ajax安全问题,对于敏感数据在服务器端处理,避免在客户端处理过滤。对于关键业务逻辑代码也必须放在服务器端处理。

    谈谈this的理解

    • this总是指向函数的直接调用者(而非间接调用者)
    • 如果有new关键字,this指向new出来的那个对象
    • 在事件中,this指向目标元素,特殊的是IE的attachEvent中的this总是指向全局对象window。

    什么是window对象? 什么是document对象?

    window对象代表浏览器中打开的一个窗口。document对象代表整个html文档。实际上,document对象是window对象的一个属性。

    null,undefined的区别?

    null表示一个对象被定义了,但存放了空指针,转换为数值时为0。
    undefined表示声明的变量未初始化,转换为数值时为NAN。

    typeof(null) -- object;
    typeof(undefined) -- undefined
    

    new操作符具体干了什么呢?

    • 创建一个空对象,并且 this 变量引用该对象,同时还继承了该函数的原型。
    • 属性和方法被加入到 this 引用的对象中。
    • 新创建的对象由 this 所引用,并且最后隐式的返回 this 。

    同步和异步的区别?

    同步的概念在操作系统中:不同进程协同完成某项工作而先后次序调整(通过阻塞、唤醒等方式),同步强调的是顺序性,谁先谁后。异步不存在顺序性。

    • 同步:浏览器访问服务器,用户看到页面刷新,重新发请求,等请求完,页面刷新,新内容出现,用户看到新内容之后进行下一步操作。
    • 异步:浏览器访问服务器请求,用户正常操作,浏览器在后端进行请求。等请求完,页面不刷新,新内容也会出现,用户看到新内容。

    回流与重绘

    当渲染树中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建。这就称为回流(reflow)。每个页面至少需要一次回流,就是在页面第一次加载的时候。在回流的时候,浏览器会使渲染树中受到影响的部分失效,并重新构造这部分渲染树。完成回流后,浏览器会重新绘制受影响的部分到屏幕中,该过程成为重绘

    DOM操作

    • 创建新节点
      createDocumentFragment() //创建一个DOM片段
      createElement() //创建一个具体的元素
      createTextNode() //创建一个文本节点
    • 添加、移除、替换、插入
      appendChild()
      removeChild()
      replaceChild()
      insertBefore() //在已有的子节点前插入一个新的子节点
    • 查找
      getElementsByTagName() //通过标签名称
      getElementsByName() //通过元素的Name属性的值(IE容错能力较强,会得到一个数组,其中包括id等于name值的)
      getElementById() //通过元素Id,唯一性

    数组对象有哪些原生方法,列举一下

    pop、push、shift、unshift、splice、reverse、sort、concat、join、slice、toString、indexOf、lastIndexOf、reduce、reduceRight、forEach、map、filter、every、some

    哪些操作会造成内存泄漏

    全局变量、闭包、DOM清空或删除时,事件未清除、子元素存在引用

    请描述一下cookie,sessionStorage和localStorage的区别

    • localStorage长期存储数据,浏览器关闭数据后不丢失;
    • sessionStorage数据在浏览器关闭后自动删除;
    • cookie是网站为了标识用户身份而存储在用户本地终端(Client Side)上的数据(通常经过加密)。cookie始终在同源的http请求中携带(即使不需要)都会在浏览器和服务器端间来回传递。session storage和local storage不会自动把数据发给服务器,仅在本地保存;
    • 存储大小:cookie数据大小不会超过4K,session storage和local storage虽然也有存储大小的限制,但比cookie大得多,可以达到5M或者更多;
    • 有期时间:local storage存储持久数据,浏览器关闭后数据不丢失,除非自动删除数据。session storage数据在当前浏览器窗口关闭后自动删除。cookie 设置的cookie过期时间之前一直有效,即使窗口或者浏览器关闭;

    http状态码有那些?分别代表是什么意思?列举2-3个熟悉的状态码

    当用户在浏览网页的时候,浏览器会返回一个htttp状态码,主要是用来响应浏览器的请求。

    • 200 OK 请求正常处理完毕
    • 204 No Content 请求成功处理,没有实体的主体返回
    • 301 Moved Permanently 永久重定向,资源已永久分配新URI
    • 302 Found 临时重定向,资源已临时分配新URI
    • 400 Bad Request 请求报文语法错误或参数错误
    • 401 Unauthorized 要通过HTTP认证,或认证失败
    • 403 Forbidden 请求资源被拒绝
    • 404 Not Found 无法找到请求资源(服务器无理由拒绝)
    • 500 Internal Server Error 服务器故障或Web应用故障
    • 503 Service Unavailable 服务器超负载或停机维护你可以关闭;

    一个 http 请求由什么组成?

    请求的方法:post,get
    正在请求的URL:请求的地址
    请求头:客户端环境信息,身份验证信息
    请求体:表单信息等

    http协议的 三次握手/四次挥手,可以描述一下吗?

    http的三次握手和四次挥手:
    浏览器在给服,务器传输数据之前,有三次握手,握手成功之后,才可以传输数据

    • 浏览器需要先发送SYN码,客户端请求和服务器建立连接;
    • 服务器接收到SYN码,再发送给客户端SYN+ACK码,我可以建立连接;
    • 客户端接收到ACK码,验证这个ACK是否正确,如果正确则客户端和服务端则建立起数据连接;双方的数据发送通道都将开启;

    四次挥手:

    • 当客户端无数据要传输了,会发送FIN码告诉服务器,我发送完毕了;
    • 当服务器接收完毕后,告诉客户端ACK码,告诉客户端你可以把数据通道关闭了;
    • 当服务器发送完毕之后,也会发送FIN码,告诉浏览器,数据发送完毕;
    • 当客户端接收完毕 之后,同样发送ACK码,告诉服务器,数据接收 完毕,

    ajax请求的时候get 和post方式的区别?

    1.使用Get请求时,参数在URL中显示,而使用Post方式,则不会显示出来
    2.使用Get请求发送数据量小,Post请求发送数据量大

    什么是防抖和节流?有什么区别?如何实现?

    防抖:
    触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间

    • 举个栗子
      每次触发事件时都取消之前的延时调用方法
    function debounce(fn) {
          let timeout = null; // 创建一个标记用来存放定时器的返回值
          return function () {
            clearTimeout(timeout); // 每当用户输入的时候把前一个 setTimeout clear 掉
            timeout = setTimeout(() => { // 然后又创建一个新的 setTimeout, 这样就能保证输入字符后的 interval 间隔内如果还有字符输入的话,就不会执行 fn 函数
              fn.apply(this, arguments);
            }, 500);
          };
        }
        function sayHi() {
          console.log('防抖成功');
        }
        var inp = document.getElementById('inp');
        inp.addEventListener('input', debounce(sayHi)); // 防抖
    

    节流:
    高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的执行频率

    • 举个栗子
      每次触发事件时都判断当前是否有等待执行的延时函数
    function throttle(fn) {
          let canRun = true; // 通过闭包保存一个标记
          return function () {
            if (!canRun) return; // 在函数开头判断标记是否为true,不为true则return
            canRun = false; // 立即设置为false
            setTimeout(() => { // 将外部传入的函数的执行放在setTimeout中
              fn.apply(this, arguments);
              // 最后在setTimeout执行完毕后再把标记设置为true(关键)表示可以执行下一次循环了。当定时器没有执行的时候标记永远是false,在开头被return掉
              canRun = true;
            }, 500);
          };
        }
        function sayHi(e) {
          console.log(e.target.innerWidth, e.target.innerHeight);
        }
        window.addEventListener('resize', throttle(sayHi));
    
    

    持续更新中......

    相关文章

      网友评论

          本文标题:前端面试题之js篇(以及网络协议、储存)

          本文链接:https://www.haomeiwen.com/subject/xeesrrtx.html