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
取值符合以下规则:
- 在调用函数时使用
new
关键字,函数内的this
是一个全新的对象。 - 如果
apply
、call
或bind
方法用于调用、创建一个函数,函数内的 this 就是作为参数传入这些方法的对象。 - 当函数作为对象里的方法被调用时,函数内的
this
是调用该函数的对象。比如当obj.method()
被调用时,函数内的 this 将绑定到obj
对象。 - 如果调用函数不符合上述规则,那么
this
的值指向全局对象(global object)。浏览器环境下this
的值指向window
对象,但是在严格模式下('use strict'
),this
的值为undefined
。 - 如果符合上述多个规则,则较高的规则(1 号最高,4 号最低)将决定
this
的值。 - 如果该函数是 ES2015 中的箭头函数,将忽略上面的所有规则,
this
被设置为它被创建时的上下文。
想获得更深入的解释,请查看他在 Medium 上的文章。
https://github.com/yangshun/f...
如何确定this指向
如果要判断一个运行中函数的 this 绑定,就需要找到这个函数的直接调用位置。找到之后就可以顺序应用下面这四条规则来判断 this 的绑定对象。
- 由 new 调用?绑定到新创建的对象。
- 由 call 或者 apply (或者 bind )调用?绑定到指定的对象。
- 由上下文对象调用?绑定到那个上下文对象。
- 默认:在严格模式下绑定到 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
对象,就是定义时所在的对象,而不是使用时所在的对象,用call
apply
bind
也不能改变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...
页面大量图片,如何优化加载,优化用户体验
- 图片懒加载。在页面的未可视区域添加一个滚动事件,判断图片位置与浏览器顶端的距离与页面的距离,如果前者小于后者,优先加载。
- 如果为幻灯片、相册等,可以使用图片预加载技术,将当前展示图片的前一张和后一张优先下载。
- 如果图片为css图片,可以使用CSSsprite,SVGsprite等技术。
- 如果图片过大,可以使用特殊编码的图片,加载时会先加载一张压缩的特别厉害的缩略图,以提高用户体验。
- 如果图片展示区域小于图片的真实大小,应在服务器端根据业务需要先进行图片压缩,图片压缩后大小与展示一致。
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...