原生JS面试题2

三、js跨域问题怎么解决?
1、 JSONP跨域请求
要理解跨域,先要了解一下”同源策略“。所谓同源是指,协议、域名、端口都相同。所谓”同源策略“,简单的说,就是基于安全考虑,当前域不能访问其他域的东西。
http 和 https :协议不同
www.a.com 和 www.b.com :域名不同
www.a.com : 8080 和 www.a.com : 1000 : 端口不同

在同源策略下,在某个服务器下的页面是无法获取到该服务器以外的数据的。
例如我们在自己的网站通过 ajax 去 获取豆瓣上的图书接口:
https://api.douban.com/v2/book/search?q=javascript&count=1

我们通过以上 ajax 去访问,发现运行时会报错:
在这里插入图片描述
只要出现这个错误,就说明服务器接口不支持跨域
//No ‘Access-Control-Allow-Origin’ header is present on the requested resource
这是因为不同源,所以无法访问其他服务器的数据

但是 img的 src ( 获取图片 ) , link 的 href (获取css),script 的 src (获取js)这三个属性都不符合同源策略,它们可以跨域获取数据。JSONP就是利用script 的 src 来实现跨域获取数据。

跨域原理
JSONP实现跨域请求的原理,简单的说,就说动态创建
script标签,然后利用script的 src 不受同源策略的约束来跨域获取数据。
JSONP 由两部分组成:回调函数和数据。回调函数 是当响应到来时,应该在页面中调用的函数。回调函数的名字,一般是在请求中指定的。而数据就是传入回调函数中的 JSON 数据。

注意:JSONP不是真正的 ajax
ajax是异步的,jsonp是同步的,所以它不是真正的ajax

动态创建 script>标签,设置其 src ,回调函数在 src 中设置:

var script = document.createElement("script");
script.src = "https://api.douban.com/v2/book/search?q=javascript&count=1";
document.body.insertBefore( script, document.body.firstChild );

在页面中,返回的 JSON 作为参数传入 回调函数中,我们通过回调函数来 操作数据

function handleResponse(response){
    //对 response 数据进行操作代码
}

了解了 JSONP 的基本使用方法,我们在实现上面,通过 ajax 调用豆瓣接口的需求,实现代码如下:
在这里插入图片描述
注意:以上代码中,要记得成功访问完数据后,要删除创建的动态 script标签:document.body.removeChild(script)

其实在接口数据的形式类似:fn( { name: “张三” , age: “20” } ) ,我们传递过去一个和这个函数名字相同的回调函数,参数就是访问到的数据。
假如接口是:

http://api.money.126.net/data/feed/0000001,1399001?callback=refreshPrice

函数名就是 callbanck = 的值:refreshPrice.

JSONP目前还是比较流行的跨域方式,虽然JSONP使用起来方便,但是也存在一些问题:如果其他域不安全,很可能会在响应中夹带一些恶意代码。而且要确定 JSONP请求是否失败并不容易。
JSONP有个限制,只能用GET请求,并且要求返回JavaScript

更多跨域的方法介绍:
https://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000/001434499861493e7c35be5e0864769a2c06afb4754acc6000
对ajax有更进一步的理解,利用cros进行跨域处理!!!

2、CROS跨域

3、反向代理

四、闭包
概念:闭包就是能够读取其他函数内部变量的函数
由于函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数”(然后将这个内部的函数 return 返回出来)。
所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁

闭包的作用:它最大的用处有两个: 1) 一个是可以读取函数内部的变量;
2) 另一个就是让这些变量的值始终保存在内存中。

使用闭包的注意点:1) 由于闭包会使得函数中的变量都保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄漏。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

内存泄漏:程序的运行需要内存。对于持续运行的服务进程,必须及时释放不再用到的内存,否则占用越来越高,轻则影响系统性能,重则导致进程崩溃。不再用到的内存,没有及时释放,就叫做内存泄漏。
http://www.ruanyifeng.com/blog/2017/04/memory-leak.html

2) 闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法,把内部变量当作它的私有属性,这时一定要小心,不要随便改变父函数内部变量的值。

五、promise的用法和原理?
概念:promise 是异步编程的一种解决方案。它可以把异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。
Promise 为异步操作提供了统一的接口,使得控制异步操作更加容易,它的强大之处在于它的链式调用。

基本用法:

new Promise(function(resolve, reject) {
//待处理的异步逻辑
//处理结束后,调用resolve或reject方法
})

新建一个promise很简单,只需要new 一个 Promise 对象即可。所以promise本质上就是一个函数,它接受一个函数作为参数,并且返回promise对象,这就给链式调用提供了基础。

特点:
1、对象的状态不受外界影响。 Promise 的实例 有以下三种状态: 1)pending : 进行中 2)resolved : 已成功完成 3)rejected : 已失败

只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。

2、一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为resolved;从pending变为rejected。 只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。
基本用法:
ES6规定,Promise 对象是一个构造函数,用来生成Promise
实例
在这里插入图片描述

Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由JavaScript 引擎提供, 不是自己部署。

resolve函数的作用,将Promise对象的状态从“进行中”变成 “成功”( 即从pending变为resolved ) ,在异步操作成功时调用,并将异步操作的结果,作为参数传递出去。
reject函数的作用,在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。

Promise实例生成以后,可以用then方法分别制定 Resolved状态和Rejected状态的回调函数:
在这里插入图片描述

then方法可以接受 2 个回调函数作为参数,第二个函数是可选的,不一定要提供。这两个函数都接受Promise对象传出的值作为参数。

promise捕获错误 .catch方法:

Promise.prototype.catch方法是Promise.prototype.then(null,
rejection)的别名,用于指定发生错误时的回调函数。

在这里插入图片描述
Promise对象的错误具有“ 冒泡 ”性质,会一直向后传递,直到被捕获为止。也就是说,错误总是会被下一个catch语句捕获。
在这里插入图片描述
题外话:async 函数是es7 提案出来的语法, async函数是用来取代回调函数的另一种方法。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值