基于上次腾讯远程面试的题目总结与回答(精心总结回顾) 上

本文深入讲解了前端开发中的核心知识点,包括使用XMLHttpRequest实现AJAX请求的详细步骤、事件流机制的理解与应用、闭包的概念及其应用场景、改变函数上下文的方法如call和apply的使用,以及解决跨域问题的技术方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这篇博客同步更新于我的GitHub博客:我的GitHub博客

面试回顾:腾讯面试回顾

1.js中ajax发送请求的步骤

在js中,有一个用于异步请求的对象,XMLHttpRquest对象,使用该对象可以向服务端发送请求(post,get,put...)。原生的方法步骤如下:

①创建XMLHttpRequest对象(标准浏览器):

if(window.XMLHttpRequest){
  var xhr = new XMLHttpRequest();
}

IE7及以下,这个对象为:ActiveXObject:

if(window.ActiveXObject){
var xhr = new ActiveXObject('Microsoft.XMLHTTP')
}

② 初始化请求

xhr.open('GET','http://www.请求地址.com',是否异步?true:false);

③发送请求/传递数据

xhr.send();

请求的文件路径,如果是GET方式,直接缀在请求地址的后面,以如下的形式:

//数据
xhr.open('GET','http://www.请求地址.com/index.html',true);

如果是POST方法,直接写 xhr.send('数据') 中。

④设置异步回调callback()
先给个错误示范:

//xhr.readyState 本地的请求状态
//xhr.status 服务器返回的请求状态码
if(xhr.readystate==4 && xhr.status == 200){
  do something...
}

这里的本质原因是没有本地xhr对象改变的事件,因此这里的readystate会一直长等于 1

这里的异步方式主要通过一个事件来完成:

xhr.onreadystatechange()=function(){

if(xhr.readystate==4 && xhr.status == 200){
  do something...
}

}

如果在步骤②中请求的方式是同步的,一旦服务器压力过大,没有及时响应,那么代码会一直卡在这里,一直傻傻的等到服务器响应200,才会do something。

反之,如果请求方式是异步的,那么这里的响应无论是否及时,都不会阻塞后面的代码。

扩展:既然 readyState==4 && status ==200 是一个回调,那么我们也可以使用其他的http状态码来设置不同的回调~
参考文章 ,我以前的博客:Ajax初探
上一次的面试中,xhr.open()初始化 xhr.send()发送请求 xhr.onreadystatechange=function(){}回调函数 这三点都忘记答了,一定要注意。

2.浏览器里面的事件都会按照一定的规则去传递,这个规则是什么?

事件捕获、事件响应、事件冒泡。

如图:

事件捕获和冒泡

不管body上绑定事件、或者div甚至div的text节点上绑定事件,这个事件必须先从根节点开始遍历(即Window对象开始),从上往下,传递的过程中,发现有的元素绑定了事件,也先放着,等全部事件捕获完毕(遍历完毕), 开始处理事件,处理的顺序为,从最小的根节点上的事件开始,依次向上冒泡。

一句话概括这种机制:

捕获:自外而内,从根到叶,从大到小 。

冒泡:自内而外,从叶到根,从小到大。

来做个实验,有如下的html结构 和 js代码:

<!--HTML结构-->
<div id="div1">
        我是DIV1
        <div id="div2">
            我是DIV2
            <button id="btn">
                i am a button
            </button>
        </div>
    </div>


//script代码

var div1 = document.getElementById('div1');
var div2 = document.getElementById('div2');
var btn = document.getElementById('btn');

btn.addEventListener('click', function() {console.log(this.id)},false);


div2.addEventListener('click', function(){console.log(this.id)},false);

div1.addEventListener('click', function(){console.log(this.id)},false);

HTML结构如图:

HTML结构

当点击最里面的button,会依次出现这种情况:

控制台输出

可以看到,事件是在冒泡阶段被触发的。

当改变js API中最后一个Boolean值为true时,又会产生另外一种景观:

这里写图片描述

这次是从外向内依次触发的。

总结:
1.addEventListener(事件,函数,boolean?捕获:冒泡),这个API可以设置事件触发于捕获/冒泡阶段,而且这个事件可以复写。
2.普通的API,例如 onclick ,onmouse 默认只能在冒泡阶段触发,而且不能复写,复写事件会覆盖。

3.闭包是怎么回事?用在什么场景?

简而言之:1、闭包就是可以访问局部作用域的变量。
并且: 2、 可以使局部变量常驻内存
参考阮一峰老师的闭包博客: 阮一峰—-闭包

Q:闭包的内部函数为什么变量不会被销毁?
A:

function a(){
var a =1;

function b(){
a+=1;
return a;
}
return b();

}

因为此时的子函数b一直对于a函数的变量“a=1”有需求,因此这个变量会常驻内存,不会被销毁。

Q 3.1:什么时候才能够销毁这个内存呢?(销毁机制和人为销毁方法)

A:浏览器中的js引擎有自己的垃圾回收机制,当一个变量或者对象引用为0的时候,会自动回收。
人为的销毁内存的办法:1.关闭网页,结束js运行环境。2.销毁变量,为变量赋值 null;

Q3.2:如何避免内存泄漏的问题?
A:减少全局空间的污染,良好的变量定义习惯。减少变量的引用。

4.CALL和Apply是干嘛的?

二者都是为了更改function 的this指针,举个例子

CALL(新的this对象,原先的参数1,原先的参数2…);
Apply(新的this对象,[原先的参数1,原先的参数2…]);

先传入新的this对象,再传入旧方法的传参。

5.在平时开发中,遇到过跨域的问题吗?如何处理跨域呢?

1.jsonp跨域
利用<script>标签的跨域特性,将请求的语句写在script标签的src属性上,然后定义一个方法,用于接受返回值responseText。代码如下:

        //在js预先定义好callback()函数  

        function fun(data){

            //use data to do somethings.

        }


        //动态创建script标签,并在url中说明请求地址
        var body = document.getElementsByTagName('body')[0];

        var script = document.createElement('script');

        script.type = 'text/javasctipt';

        script.src = 'require.php?callback=fun';

        body.appendChild(script);

        //Script插入完成,一旦服务端有响应,传递过来的响应文本会直接被当做js代码执行。
           //假设传回的值是 fun({"name":"xiaoming"}),那么小明这个对象会被当做参数传递给早就定义好的fun()函数。

这样,通过script不受跨域访问的特性,实现了跨域访问。

2.CORS跨域(主流浏览器及IE10+)
对于客户端,我们还是正常使用xhr对象发送ajax请求。
唯一需要注意的是,我们需要设置我们的xhr属性withCredentials为true,不然的话,cookie是带不过去的哦,设置: xhr.withCredentials = true;
对于服务器端,需要在 response header中设置如下两个字段:
Access-Control-Allow-Origin: http://www.yourhost.com
Access-Control-Allow-Credentials:true
这样,我们就可以跨域请求接口了。

3.返回的json和jsonp有什么区别?
返回的json是json格式的文件,而返回的jsonp是字符串形式的文件,形如:

callback({"name":"HanMeiMei"})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值