2019前端最全面试题(五)

简介: 2019前端最全面试题(五)

bind、call、apply的区别

call和apply其实是一样的,区别就在于传参时参数是一个一个传或者是以一个数组的方式来传。


call和apply都是在调用时生效,改变调用者的this指向。

let name = 'Jack'
const obj = {name: 'Tom'}
function sayHi() {console.log('Hi! ' + this.name)}
sayHi() // Hi! Jack
sayHi.call(obj) // Hi! Tom

bind也是改变this指向,不过不是在调用时生效,而是返回一个新函数。

const newFunc = sayHi.bind(obj)
newFunc() // Hi! Tom

请简述JavaScript中的this

JS 中的this是一个相对复杂的概念,不是简单几句能解释清楚的。粗略地讲,函数的调用方式决定了this的值。我阅读了网上很多关于this的文章,Arnav Aggrawal 写的比较清楚。this取值符合以下规则:

  1. 在调用函数时使用new关键字,函数内的this是一个全新的对象。
  2. 如果applycallbind方法用于调用、创建一个函数,函数内的 this 就是作为参数传入这些方法的对象。
  3. 当函数作为对象里的方法被调用时,函数内的this是调用该函数的对象。比如当obj.method()被调用时,函数内的 this 将绑定到obj对象。
  4. 如果调用函数不符合上述规则,那么this的值指向全局对象(global object)。浏览器环境下this的值指向window对象,但是在严格模式下('use strict'),this的值为undefined
  5. 如果符合上述多个规则,则较高的规则(1 号最高,4 号最低)将决定this的值。
  6. 如果该函数是 ES2015 中的箭头函数,将忽略上面的所有规则,this被设置为它被创建时的上下文。

想获得更深入的解释,请查看他在 Medium 上的文章

https://github.com/yangshun/f...

如何确定this指向

如果要判断一个运行中函数的 this 绑定,就需要找到这个函数的直接调用位置。找到之后就可以顺序应用下面这四条规则来判断 this 的绑定对象。

  1. 由 new 调用?绑定到新创建的对象。
  2. 由 call 或者 apply (或者 bind )调用?绑定到指定的对象。
  3. 由上下文对象调用?绑定到那个上下文对象。
  4. 默认:在严格模式下绑定到 undefined ,否则绑定到全局对象。

一定要注意,有些调用可能在无意中使用默认绑定规则。如果想“更安全”地忽略 this 绑定,你可以使用一个 DMZ 对象,比如 ø = Object.create(null) ,以保护全局对象。


ES6 中的箭头函数并不会使用四条标准的绑定规则,而是根据当前的词法作用域来决定this ,具体来说,箭头函数会继承外层函数调用的 this 绑定(无论 this 绑定到什么)。这其实和 ES6 之前代码中的 self = this 机制一样

参考:《你不知道的JavaScript》

== 和 ===的区别是什么

==是抽象相等运算符,而===是严格相等运算符。==运算符是在进行必要的类型转换后,再比较。===运算符不会进行类型转换,所以如果两个值不是相同的类型,会直接返回false。使用==时,可能发生一些特别的事情,例如:

1 == '1'; // true
1 == [1]; // true
1 == true; // true
0 == ''; // true
0 == '0'; // true
0 == false; // true

如果你对=====的概念不是特别了解,建议大多数情况下使用===

箭头函数和普通函数有什么区别

  • 函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象,用callapplybind也不能改变this指向
  • 不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。
  • 不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
  • 不可以使用yield命令,因此箭头函数不能用作 Generator 函数。
  • 箭头函数没有原型对象prototype

首屏时间、白屏时间

Performance 接口可以获取到当前页面中与性能相关的信息。


该类型的对象可以通过调用只读属性 Window.performance 来获得。


白屏时间:

performance.timing.responseStart - performance.timing.navigationStart

首屏时间

window.onload = () => {
    new Date() - performance.timing.responseStart
}
https://developer.mozilla.org...

当你在浏览器输入一个地址后发生了什么

https://github.com/skyline754...

页面大量图片,如何优化加载,优化用户体验

  1. 图片懒加载。在页面的未可视区域添加一个滚动事件,判断图片位置与浏览器顶端的距离与页面的距离,如果前者小于后者,优先加载。
  2. 如果为幻灯片、相册等,可以使用图片预加载技术,将当前展示图片的前一张和后一张优先下载。
  3. 如果图片为css图片,可以使用CSSsprite,SVGsprite等技术。
  4. 如果图片过大,可以使用特殊编码的图片,加载时会先加载一张压缩的特别厉害的缩略图,以提高用户体验。
  5. 如果图片展示区域小于图片的真实大小,应在服务器端根据业务需要先进行图片压缩,图片压缩后大小与展示一致。

https://www.jianshu.com/p/5d8...

js网络请求性能优化之防抖与节流

  • 防抖(debounce)

在函数需要频繁触发时,只有当有足够空闲的时间时,才执行一次。就好像在百度搜索时,每次输入之后都有联想词弹出,这个控制联想词的方法就不可能是输入框内容一改变就触发的,他一定是当你结束输入一段时间之后才会触发。

  • 节流(thorttle)

预定一个函数只有在大于等于执行周期时才执行,周期内调用不执行。就好像你在淘宝抢购某一件限量热卖商品时,你不断点刷新点购买,可是总有一段时间你点上是没有效果,这里就用到了节流,就是怕点的太快导致系统出现bug。

  • 区别

在发生持续触发事件时,防抖设置事件延迟并在空闲时间去触发事件,而节流则是隔一定的时间触发一次。

具体请看:


https://blog.csdn.net/jacoox/...

如何做到修改url参数页面不刷新

HTML5引入了 history.pushState()history.replaceState() 方法,它们分别可以添加和修改历史记录条目。

let stateObj = {
    foo: "bar",
};
history.pushState(stateObj, "page 2", "bar.html");

假设当前页面为 foo.html,执行上述代码后会变为 bar.html,点击浏览器后退,会变为 foo.html,但浏览器并不会刷新。

pushState() 需要三个参数: 一个状态对象, 一个标题 (目前被忽略), 和 (可选的) 一个 URL. 让我们来解释下这三个参数详细内容:

  • 状态对象 — 状态对象 state 是一个 JavaScript 对象,通过 pushState () 创建新的历史记录条目。无论什么时候用户导航到新的状态,popstate 事件就会被触发,且该事件的 state 属性包含该历史记录条目状态对象的副本。

状态对象可以是能被序列化的任何东西。原因在于 Firefox 将状态对象保存在用户的磁盘上,以便在用户重启浏览器时使用,我们规定了状态对象在序列化表示后有640k的大小限制。如果你给 pushState() 方法传了一个序列化后大于 640k 的状态对象,该方法会抛出异常。如果你需要更大的空间,建议使用 sessionStorage 以及 localStorage.

  • 标题 — Firefox 目前忽略这个参数,但未来可能会用到。传递一个空字符串在这里是安全的,而在将来这是不安全的。二选一的话,你可以为跳转的 state 传递一个短标题。
  • URL — 该参数定义了新的历史URL记录。注意,调用 pushState() 后浏览器并不会立即加载这个 URL,但可能会在稍后某些情况下加载这个 URL,比如在用户重新打开浏览器时。新URL不必须为绝对路径。如果新URL是相对路径,那么它将被作为相对于当前 URL 处理。新 URL 必须与当前URL同源,否则 pushState() 会抛出一个异常。该参数是可选的,缺省为当前 URL。

格式化金钱,每千分位加逗号

function format(str) {
    let s = ''
    let count = 0
    for (let i = str.length - 1; i >= 0; i--) {
        s = str[i] + s
        count++
        if (count % 3 == 0 && i != 0) {
            s = ',' + s
        }
    }
    return s
}
function format(str) {
    return str.replace(/(\d)(?=(?:\d{3})+$)/g, '$1,')
}

请用js去除字符串空格

去除所有空格

str.replace(/\s/g, '')

去除两边空格

str.replace(/^\s+|\s+$/g, '')
// 原生方法
str.trim()


HTTP问题

RESTful

REST 指的是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是 RESTful。

  • GET

get方法在Rest中主要用于获取资源,能够发送参数,不过有限制,且参数都会以?开头的形 式附加在URL尾部。

规范的get方法处理器应该是幂等的,也就是说对一个资源不论发送多少次get请求都不会更改数据或造成破坏。

  • POST

post方法在Rest请求中主要用于添加资源,参数信息存放在请求报文的消息体中相对安全,且可发送较大信息

  • PUT

put方法在Rest中主要用于更新资源,因为大多数浏览器不支持put和delete,会自动将put和delete请求转化为get和post. 因此为了使用put和delete方法,

需要以post发送请求,在表单中使用隐藏域发送真正的请求。

put方法的参数是同post一样是存放在消息中的,同样具有安全性,可发送较大信息。

put方法是幂等的,对同一URL资源做出的同一数据的任意次put请求其对数据的改变都是一致的。

  • DELETE

Delete在Rest请求中主要用于删除资源,因为大多数浏览器不支持put和delete,会自动将put和delete请求转化为get和post。

因此为了使用put和delete方法,需要以post发送请求,在表单中使用隐藏域发送真正的请求。

Delete方法的参数同post一样存放在消息体中,具有安全性,可发送较大信息 Delete方法是幂等的,不论对同一个资源进行多少次delete请求都不会破坏数据

https://blog.csdn.net/jnshu_i...

GET和POST的区别

  • GET产生一个TCP数据包;POST产生两个TCP数据包。
  • GET在浏览器回退时是无害的,而POST会再次提交请求。
  • GET产生的URL地址可以被Bookmark,而POST不可以。
  • GET请求会被浏览器主动cache,而POST不会,除非手动设置。
  • GET请求只能进行url编码,而POST支持多种编码方式。
  • GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
  • GET请求在URL中传送的参数是有长度限制的,而POST么有。
  • 对参数的数据类型,GET只接受ASCII字符,而POST没有限制。
  • GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
  • GET参数通过URL传递,POST放在Request body中。

Accept和Content-Type

Accept 请求头用来告知客户端可以处理的内容类型,这种内容类型用MIME类型来表示。

服务器使用 Content-Type 应答头通知客户端它的选择。

Accept: text/html
Accept: image/*
Accept: text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8

1.Accept属于请求头, Content-Type属于实体头。


Http报头分为通用报头,请求报头,响应报头和实体报头。


请求方的http报头结构:通用报头|请求报头|实体报头


响应方的http报头结构:通用报头|响应报头|实体报头

2.Accept代表发送端(客户端)希望接受的数据类型。


比如:Accept:text/xml;


代表客户端希望接受的数据类型是xml类型

Content-Type代表发送端(客户端|服务器)发送的实体数据的数据类型。


比如:Content-Type:text/html;


代表发送端发送的数据格式是html。

二者合起来,


Accept:text/xml;


Content-Type:text/html


即代表希望接受的数据类型是xml格式,本次请求发送的数据的数据格式是html。

状态码

状态码 类别 描述
1xx Informational(信息状态码) 接受请求正在处理
2xx Success(成功状态码) 请求正常处理完毕
3xx Redirection(重定向状态码) 需要附加操作已完成请求
4xx Client Error(客户端错误状态码) 服务器无法处理请求
5xx Server Error(服务器错误状态码) 服务器处理请求出错

HTTP缓存

https://segmentfault.com/a/11...

如何处理不让别人盗用你的图片,访问你的服务器资源

  • http header, 对refer做判断看来源是不是自己的网站,如果不是就拒绝
  • 通过session校验,如果不通过特定服务生成cookie和session就不能请求得到资源

Http与Https的区别

  • HTTP 的URL 以https://zhuanlan.zhihu.com/p/...什么是Http协议无状态协议?怎么解决Http协议无状态协议?无状态协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息也就是说,当客户端一次HTTP请求完成以后,客户端再发送一次HTTP请求,HTTP并不知道当前客户端是一个”老用户“。可以使用Cookie来解决无状态的问题,Cookie就相当于一个通行证,第一次访问的时候给客户端发送一个Cookie,当客户端再次来的时候,拿着Cookie(通行证),那么服务器就知道这个是”老用户“。https://zhuanlan.zhihu.com/p/...常用的HTTP方法有哪些
  • GET:用于请求访问已经被URL(统一资源标识符)识别的资源,可以通过URL传参给服务器。
  • POST:用于传输信息给服务器,主要功能与Get方法类似,但一般推荐POST方式。
  • PUT:传输文件,报文主体包含文件内容,保存到对应URL位置。
  • HEAD:获取报文首部,与GET方法类似,只是不返回报文主体,一般用于验证URL是否有效。
  • DELET:删除文件,与PUT方法相反,删除对应URL位置的文件。OPTIONS:查询相应URL支持的HTTP方法。
  • 一次完整的HTTP请求所经历的7个步骤
    HTTP通信机制是在一次完整的HTTP通信过程中,Web浏览器与Web服务器之间将完成下列7个步骤:
  • 建立TCP连接
  • 在HTTP工作开始之前,Web浏览器首先要通过网络与Web服务器建立连接,该连接是通过TCP来完成的,该协议与IP协议共同构建 Internet,即著名的TCP/IP协议族,因此Internet又被称作是TCP/IP网络。HTTP是比TCP更高层次的应用层协议,根据规则, 只有低层协议建立之后才能,才能进行更层协议的连接,因此,首先要建立TCP连接,一般TCP连接的端口号是80。
  • Web浏览器向Web服务器发送请求行
  • 一旦建立了TCP连接,Web浏览器就会向Web服务器发送请求命令。例如:GET /sample/hello.jsp HTTP/1.1。
  • Web浏览器发送请求头
  • 浏览器发送其请求命令之后,还要以头信息的形式向Web服务器发送一些别的信息,之后浏览器发送了一空白行来通知服务器,它已经结束了该头信息的发送。
  • Web服务器应答
  • 客户机向服务器发出请求后,服务器会客户机回送应答, HTTP/1.1 200 OK ,应答的第一部分是协议的版本号和应答状态码。
  • Web服务器发送应答头
  • 正如客户端会随同请求发送关于自身的信息一样,服务器也会随同应答向用户发送关于它自己的数据及被请求的文档。
  • Web服务器向浏览器发送数据
  • Web服务器向浏览器发送头信息后,它会发送一个空白行来表示头信息的发送到此为结束,接着,它就以Content-Type应答头信息所描述的格式发送用户所请求的实际数据。
  • Web服务器关闭TCP连接
  • 一般情况下,一旦Web服务器向浏览器发送了请求数据,它就要关闭TCP连接,然后如果浏览器或者服务器在其头信息加入了这行代码:
Connection:keep-alive
  • TCP连接在发送后将仍然保持打开状态,于是,浏览器可以继续通过相同的连接发送请求。保持连接节省了为每个请求建立新连接所需的时间,还节约了网络带宽。
    建立TCP连接->发送请求行->发送请求头->(到达服务器)发送状态行->发送响应头->发送响应数据->断TCP连接
    https://juejin.im/post/5a8102...
目录
相关文章
|
4月前
|
Java C++ Python
试题 基础练习 闰年判断
试题 基础练习 闰年判断
14 0
|
4月前
|
Java C++ Python
试题 基础练习 数列特征
试题 基础练习 数列特征
13 0
|
4月前
|
Java C++ Python
试题 基础练习 特殊回文数
试题 基础练习 特殊回文数
21 0
|
9月前
|
存储 缓存 JavaScript
2019前端最全面试题(六)
2019前端最全面试题(六)
36 0
|
9月前
|
数据采集 缓存 移动开发
2019前端最全面试题(四)
2019前端最全面试题(四)
58 0
|
9月前
|
Web App开发 前端开发 JavaScript
2019前端最全面试题(三)
2019前端最全面试题(三)
33 0
|
9月前
|
编解码 前端开发 JavaScript
2019前端最全面试题(二)
2019前端最全面试题(二)
30 1
|
4月前
|
Java C++ Python
试题 基础练习 数列排序
试题 基础练习 数列排序
16 0
|
9月前
|
缓存 前端开发 JavaScript
前端面试基础题库——1
前端面试基础题库——1
125 0
|
4月前
|
XML 存储 前端开发
2022最新前端经典面试试题
2022最新前端经典面试试题