0%

JS高频考题分享


Javascript的一些题目无非就是靠this的指向,但是有一些是真的十分容易混淆

抄录知乎的地址

, = 运算符和this指向

废话不多说,直接上题

1
2
3
4
5
6
7
8
9
10
11
12
var out = 25,
inner = {
out: 20,
func: function () {
var out = 30;
return this.out;
}
};
console.log((inner.func, inner.func)());
console.log(inner.func());
console.log((inner.func)());
console.log((inner.func = inner.func)());

结果:25,20,20,25

代码解析:这道题的考点分两个

作用域

  1. 运算符(赋值预算,逗号运算)
  2. 先看第一个输出:25,因为 ( inner.func, inner.func ) 是进行逗号运算符,逗号运算符就是运算前面的 ”,“ 返回最后一个,举个栗子
1
2
3
4
5
var i = 0, j = 1, k = 2;
console.log((i++, j++, k)) // 返回的是 k 的值 2 ,如果写成 k++ 的话 这里返回的就是 3
console.log(i); // 1
console.log(j); // 2
console.log(k); // 2

回到原题 ( inner.func, inner.func ) 就是返回 inner.func ,而 inner.func 只是一个匿名函数

1
2
3
4
function () {
var out = 30;
return this.out;
}

而且这个匿名函数是属于 window 的,则变成了

1
2
3
4
(function () {
var out = 30;
return this.out;
})()

此刻的 this => window

所以 out 是 25。

第二和第三个 console.log 的作用域都是 inner,也就是他们执行的其实是 inner.func(); inner 作用域中是有 out 变量的,所以结果是 20。

第四个 console.log 考查的是一个等号运算 inner.func = inner.func ,其实返回的是运算的结果, 举个栗子

1
2
var a = 2, b = 3;
console.log(a = b) // 输出的是 3

所以 inner.func = inner.func 返回的也是一个匿名函数

1
2
3
4
function () {
var out = 30;
return this.out;
}

此刻,道理就和第一个 console.log 一样了,输出的结果是 25。

从敲入 URL 到渲染完成的整个过程

  • 用户输入 url 地址,浏览器根据域名寻找 IP 地址
  • 浏览器向服务器发送 http 请求,如果服务器段返回以 301 之类的重定向,浏览器根据相应头中的 location 再次发送请求
  • 服务器端接受请求,处理请求生成 html 代码,返回给浏览器,这时的 html 页面代码可能是经过压缩的
  • 浏览器接收服务器响应结果,如果有压缩则首先进行解压处理,紧接着就是页面解析渲染
  • 解析渲染该过程主要分为以下步骤:解析 HTML、构建 DOM 树、DOM 树与 CSS 样式进行附着构造呈现树
  • 布局
  • 绘制

详细的在这里

JS 识别不同浏览器信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function myBrowser() {
var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串
var isOpera = userAgent.indexOf("Opera") > -1;
if (isOpera) {
return "Opera"
}; //判断是否Opera浏览器
if (userAgent.indexOf("Firefox") > -1) {
return "Firefox";
} //判断是否Firefox浏览器
if (userAgent.indexOf("Chrome") > -1) {
return "Chrome";
} //判断是否Google浏览器
if (userAgent.indexOf("Safari") > -1) {
return "Safari";
} //判断是否Safari浏览器
if (userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1 && !isOpera) {
return "IE";
}; //判断是否IE浏览器
}

哪些常见操作会造成内存泄漏

内存泄漏指任何对象在您不再拥有或需要它之后仍然存在。

垃圾回收器定期扫描对象,并计算引用了每个对象的其他对象的数量。如果一个对象的引用数量为 0(没有其他对象引用过该对象),或对该对象的惟一引用是循环的,那么该对象的内存即可回收。

setTimeout 的第一个参数使用字符串而非函数的话,会引发内存泄漏。
闭包、控制台日志、循环(在两个对象彼此引用且彼此保留时,就会产生一个循环)。

new 操作符具体干了什么呢

  • 创建一个空对象,并且 this 变量引用该对象,同时还继承了该函数的原型。
  • 属性和方法被加入到 this 引用的对象中。
  • 新创建的对象由 this 所引用,并且最后隐式的返回 this 。

合并数组

如果你需要合并两个数组的话,可以使用 Array.concat()

1
2
3
var array1 = [1, 2, 3];
var array2 = [4, 5, 6];
console.log(array1.concat(array2)); // [1,2,3,4,5,6];

然而,这个函数并不适用于合并大的数组,因为它需要创建一个新的数组,而这会消耗很多内存。

这时,你可以使用 Array.push.apply(arr1, arr2) 来代替创建新的数组,它可以把第二个数组合并到第一个中,从而较少内存消耗。

1
2
3
var array1 = [1, 2, 3];
var array2 = [4, 5, 6];
console.log(array1.push.apply(array1, array2)); // [1, 2, 3, 4, 5, 6]

Promise 的队列与 setTimeout 的队列有何关联 ?

1
2
3
4
5
6
7
8
9
10
11
setTimeout(function(){ console.log(4) }, 0);
new Promise(function(resolve){
console.log(1)
for( var i = 0 ; i < 10000 ; i++ ){
i == 9999 && resolve()
}
console.log(2)
}).then(function(){
console.log(5)
});
console.log(3);

为什么结果是:1, 2, 3, 5, 4;而不是:1, 2, 3, 4, 5 ?

js 里面有宏任务(macrotask)和微任务(microtask)。

因为 setTimeout 是属于 macrotask 的,而整个 script 也是属于一个 macrotask,promise.then 回调是 microtask,执行过程大概如下:

  • 由于整个 script 也属于一个 macrotask,由于会先执行 macrotask 中的第一个任务,再加上 promise 构造函数因为是同步的,所以会先打印出 1 和 2;
  • 然后继续同步执行末尾的 console.log(3) 打印出 3;
  • 此时 setTimeout 被推进到 macrotask 队列中, promise.then 回调被推进到 microtask 队列中;
  • 由于在第一步中已经执行完了第一个 macrotask ,所以接下来会顺序执行所有的 microtask,也就是 promise.then 的回调函数,从而打印出 5;
  • microtask 队列中的任务已经执行完毕,继续执行剩下的 macrotask 队列中的任务,也就是 setTimeout,所以打印出 4。

TCP 三次握手和四次挥手的理解

直接上图

更详细的

找出字符串中出现最多的字符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var str = 'abaasdffggghhjjkkgfddsssss3444343';
// 1.将字符串转换成数组
var newArr = str.split("");
// 2.创建一个对象
var json = {};
// 3. 所有字母出现的次数,判断对象中是否存在数组中的值,如果存在值 +1,不存在赋值为 1
for(var i = 0; i < newArr.length; i++){
// 类似:json : { ‘a’: 3, ’b’: 1 }
if(json[newArr[i]]){
json[newArr[i]] +=1;
} else {
json[newArr[i]] = 1;
}
}
// 4 定义两个变量存储字符值,字符出现的字数
var num = 0 ; //次数
var element = ""; //最多的项
for(var k in json){
if(json[k] > num){
num = json[k];
element = k ;
}
}
console.log("出现次数:"+num +"最多的字符:"+ element);

alert(1 && 2) 和 alert(1 || 0) 的结果是 ?

alert(1 &&2 ) 的结果是 2

  • 只要 “&&” 前面是 false,无论 “&&” 后面是 true 还是 false,结果都将返 “&&” 前面的值;
  • 只要 “&&” 前面是 true,无论 “&&” 后面是 true 还是 false,结果都将返 “&&” 后面的值;

alert(0 || 1) 的结果是 1

  • 只要 “||” 前面为 false,不管 “||” 后面是 true 还是 false,都返回 “||” 后面的值。
  • 只要 “||” 前面为 true,不管 “||” 后面是 true 还是 false,都返回 “||” 前面的值。

只要记住 0 与 任何数都是 0,其他反推。

感谢各位大佬的无私分享

-------------本文结束感谢您的阅读-------------
没办法,总要恰饭的嘛~~