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

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));

持续更新中......

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容