题1、
介绍 HTTPS 握手过程
答:
1、客户端使用https的url访问web服务器,要求与服务器建立ssl连接
2、web服务器收到客户端请求后, 会将网站的证书(包含公钥)传送一份给客户端
3、客户端收到网站证书后会检查证书的颁发机构以及过期时间, 如果没有问题就随机产生一个秘钥
4、客户端利用公钥将会话秘钥加密, 并传送给服务端, 服务端利用自己的私钥解密出会话秘钥
5、之后服务器与客户端使用秘钥加密传输
题2、
call 和 apply 的区别是什么,哪个性能更好一些
答:
1、Function.prototype.apply和Function.prototype.call 的作用是一样的,区别在于传入参数的不同;
2、第一个参数都是,指定函数体内this的指向;
3、第二个参数开始不同,apply是传入带下标的集合,数组或者类数组,apply把它传给函数作为参数,call从第二个开始传入的参数是不固定的,都会传给函数作为参数。
4、call比apply的性能要好,平常可以多用call, call传入参数的格式正是内部所需要的格式,参考call和apply的性能对比
题3、
为什么通常在发送数据埋点请求的时候使用的是 1x1 像素的透明 gif 图片?
答:
1、避免跨域(img 天然支持跨域)
2、利用空白gif或1x1 px的img是互联网广告或网站监测方面常用的手段,简单、安全、相比PNG/JPG体积小,1px 透明图,对网页内容的影响几乎没有影响,这种请求用在很多地方,比如浏览、点击、热点、心跳、ID颁发等等,
3、图片请求不占用 Ajax 请求限额
4、不会阻塞页面加载,影响用户的体验,只要new Image对象就好了,一般情况下也不需要append到DOM中,通过它的onerror和onload事件来检测发送状态。
<script type="text/javascript">
var thisPage = location.href;
var referringPage = (document.referrer) ? document.referrer : "none";
var beacon = new Image();
beacon.src = "http://www.example.com/logger/beacon.gif?page=" + encodeURI(thisPage)
+ "&ref=" + encodeURI(referringPage);
</script>
题4、
实现 (5).add(3).minus(2) 功能
答:
Number.prototype.add = function(n) {
return this.valueOf() + n;
};
Number.prototype.minus = function(n) {
return this.valueOf() - n;
};
题5、
Vue 的响应式原理中 Object.defineProperty 有什么缺陷?为什么在 Vue3.0 采用了 Proxy,抛弃了 Object.defineProperty?
答:
1、Object.defineProperty无法监控到数组下标的变化,导致通过数组下标添加元素,不能实时响应;
2、Object.defineProperty只能劫持对象的属性,从而需要对每个对象,每个属性进行遍历,如果,属性值是对象,还需要深度遍历。Proxy可以劫持整个对象,并返回一个新的对象。
3、Proxy不仅可以代理对象,还可以代理数组。还可以代理动态增加的属性。
题6、
冒泡排序如何实现,时间复杂度是多少, 还可以如何改进?
答:
题7、
答:
时间复杂度: n^2
function bubbleSort(arr) {
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
const temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
console.log(arr);
}
// 改进冒泡排序
function bubbleSort1(arr) {
let i = arr.length - 1;
while (i > 0) {
let pos = 0;
for (let j = 0; j < i; j++) {
if (arr[j] > arr[j + 1]) {
pos = j;
const temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
i = pos;
}
console.log(arr);
}
题8、
分析比较 opacity: 0、visibility: hidden、display: none 优劣和适用场景
答:
1、display: none (不占空间,不能点击)(场景,显示出原来这里不存在的结构)
2、visibility: hidden(占据空间,不能点击)(场景:显示不会导致页面结构发生变动,不会撑开)
3、opacity: 0(占据空间,可以点击)(场景:可以跟transition搭配)
题9、
如何把一个字符串的大小写取反(大写变小写小写变大写),例如 ’AbC’ 变成 ‘aBc’ 。
答:
function processString (s) {
var arr = s.split('');
var new_arr = arr.map((item) => {
return item === item.toUpperCase() ? item.toLowerCase() : item.toUpperCase();
});
return new_arr.join('');
}
console.log(processString('AbC'));
题10、
使用 JavaScript Proxy 实现简单的数据绑定
答:
<body>
hello,world
<input type="text" id="model">
<p id="word"></p>
</body>
<script>
const model = document.getElementById("model")
const word = document.getElementById("word")
var obj= {};
const newObj = new Proxy(obj, {
get: function(target, key, receiver) {
console.log(`getting ${key}!`);
return Reflect.get(target, key, receiver);
},
set: function(target, key, value, receiver) {
console.log('setting',target, key, value, receiver);
if (key === "text") {
model.value = value;
word.innerHTML = value;
}
return Reflect.set(target, key, value, receiver);
}
});
model.addEventListener("keyup",function(e){
newObj.text = e.target.value
})
</script>