前端面试卷五

177 阅读4分钟

下面代码输出什么

var a = 10;
(function () {

  console.log(a)

  a = 5

  console.log(window.a)

  var a = 20;

  console.log(a)
})()

// undefined 10 20

原因是作用域问题,在内部声名 var a = 20;相当于先声明 var a;然后再执行赋值操作,这是在IIFE内形成的独立作用域,如果把 var a=20 注释掉,那么 a 只有在外部有声明,显示的就是外部的A变量的值了。结果A会是 10 5 5

使用 sort() 对数组 [3, 15, 8, 29, 102, 22] 进行排序,输出结果

输出:[102, 15, 22, 29, 3, 8]

解析:根据 MDN 上对 Array.sort()的解释,默认的排序方法会将数组元素转换

为字符串,然后比较字符串中字符的 UTF-16 编码顺序来进行排序。所以'102' 会

排在 '15' 前面。

介绍 HTTPS 握手过程

1、clientHello(未加密随机数 SYN RSA)

2、SeverHello(未加密随机数 SYN+1 ACK 数字证书)

3、客户端回应  (获取数组证书中的公钥加密随机数  确认加密)

4、服务器的最后回应 (确认加密)

HTTPS 握手过程中,客户端如何验证证书的合法性

证书有效代表公钥有效:
1.校验证书的颁发机构是否受客户端信任。

2.通过 CRL 或 OCSP 的方式校验证书是否被吊销。

3.对比系统时间,校验证书是否在有效期内。

4.通过校验对方是否存在证书的私钥,判断证书的网站域名是否与证书颁

发的域名一致。

输出以下代码执行的结果并解释为什么

var obj = {
'2': 3,
'3': 4,

'length': 2,

'splice': Array.prototype.splice,

'push':Array.prototype.push}obj.push(1)obj.push(2)console.log(obj

//结果:[,,1,2], length为4的伪数组(ArrayLike)
只要类数组中含有length(可转换为数字),以及splice方法,输出该对象就会是一个数组,
push方法是根据length来决定从哪里开始插入,length=2说明从下标为2位置开始插入,所以变成了'2':1,然后length+1,然后'3':2,最后打印时前面两项为空。

实现一个 sleep 函数

比如 sleep(1000) 意味着等待 1000 毫秒,可从 Promise、Generator、Async/Await

等角度实现

//promise
console sleep = (time) =>{
    return new Promise(resolve=>{
        setTimeout(resolve,time)
    })
}

//async
function sleep(time) {
  return new Promise(resolve => setTimeout(resolve,time))
}
async function output() {
  let out = await sleep(1000);
  return out; //async函数返回一个promise
}
output();

//Generator
function* sleepGenerator(time) {
  yield new Promise(function(resolve,reject){
    setTimeout(resolve,time);
  })
}
sleepGenerator(1000).next().value.then(()=>{console.log(1)}) 
//.next:{value:promise,done:true}

双向绑定和 vuex 是否冲突

在严格模式中使用Vuex,当用户输入时,v-model会试图直接修改属性值,但这个修改不是在mutation中修改的,
所以会抛出一个错误。当需要在组件中使用vuex中的state时,有2种解决方案:1、在input中绑定value(vuex中的state),然后监听input的change或者input事件,在事件回调中调用
mutation修改state的值2、使用带有setter的双向绑定计算属性。
<input v-model="message">
//定义计算属性的settter,getter用于拦截
computed: { 
    message: { 
        get () { 
            return this.$store.state.obj.message 
        }, 
        set (value) { 
            this.$store.commit('updateMessage', value) 
        } 
    } 
}


call 和 apply 的区别是什么,哪个性能更好一些

1.Function.prototype.apply 和 Function.prototype.call 的作用是一样的,区

别在于传入参数的不同;

2.第一个参数都是,指定函数体内 this 的指向;

3. 第二个参数开始不同,apply 是传入带下标的集合,数组或者类数组,

apply 把它传给函数作为参数,call 从第二个开始传入的参数是不固定的,都会

传给函数作为参数。

4.call 比 apply 的性能要好,平常可以多用 call, call 传入参数的格式正是内

部所需要的格式,apply需要解构

为什么通常在发送数据埋点请求的时候使用的是 1x1像素的透明 gif 图片?

  1. 能够完成整个 HTTP 请求+响应(尽管不需要响应内容)

  2. 触发 GET 请求之后不需要获取和处理数据、服务器也不需要发送数据

  3. 跨域友好

  4. 执行过程无阻塞

  5. 相比 XMLHttpRequest 对象发送 GET 请求,性能上更好

  6. GIF的最低合法体积最小(最小的BMP文件需要74个字节,PNG需要67个字节,而合法的GIF,只需要43个字节)支持透明

实现 (5).add(3).minus(2) 功能。

Number.prototype.add = num =>{
    return this.valueOf() + num     //this+num也可以
}

Number.prototype.minus= num =>{
    return this.valueOf() - num    //this-num也可以
}