360| 二面 如果面试的时候遇到了良师,一定一定要抓住🎉

375 阅读7分钟

面试时长一共1小时12分钟

1、问为什么写博客,写博客是怎么坚持的?

知识沉淀,知识交流,知识深度

2、什么时候开始写博客的?

3、写博客会不会占据自己大量的时间,你怎么看?

4、代码题<div id="app"></div>拿到这个dom节点?

5、我写的是 let app = document.getElementById('app'),老师问我为什么用let?

6、let和const的区别?

let app = document.getElementById('app')这行代码用const声明也可以

7、如何判断节点的类型? 我没答上来

    <div id="app">我是一个div</div>
    <script>
        let app = document.getElementById('app')
        console.log(app.nodeType) // 1 元素节点是1 文本节点是2
        console.log(app.nodeName) // DIV
        console.log(app.childNodes[0].nodeValue); // 我是一个div
    </script>

8、如何改变节点中的文本值innerHTML/innerText/textContent

    <div id="app">我是一个div</div>
    <script>
        let app = document.getElementById('app')
        app.innerHTML = '我是改变的值'
    </script>
    <div id="app">我是一个div</div>
    <script>
        let app = document.getElementById('app')
        app.innerText = '我是改变的值'
    </script>
    <div id="app">我是一个div</div>
    <script>
        let app = document.getElementById('app')
        app.textContent  = '我是改变的值'
    </script>

思考💡:这里我就思考一下,这几个值的区别是什么innerHTML/innerText/textContent?

innerHTML指的是元素所有后代的html

innerText 不会识别display:none 和注释节点

textContent 设置成空字符串的话,所有方法都无法获取文本了

🔺:innerText的返回值依赖于页面的显示(你在页面中看到的),而textContent依赖于代码的内容

🔺:这里学习到了,innerText会触发回流,但是textContent可能不会触发回流,所以实际应用中,使用textContent性能更佳

🔺: innerTTML会返回HTML文本,textContent的内容不会解析成HTML文本,使用textContent可以防止XSS攻击

参考:

细述textContent 与 innerText、innerHTML 的区别

JavaScript innerHTML和innerText和textContent的区别

看代码

<!--
 * @Author: Kongjingjing
 * @Date: 2022-09-26 23:20:01
 * @Descripttion: 
-->
<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta http-equiv="X-UA-Compatible" content="IE=edge" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>测试</title>
		<link rel="stylesheet" href="" />
		<style></style>
	</head>
	<body>
		<div id="box">
			内容1
			<span style="display: none">内容2</span>
			<!-- 内容3 -->
			<div>
				<div>内容4</div>
			</div>
		</div>
		<script>
			var div = document.getElementById('box')
			console.log('div.innerHTML', div.innerHTML)
			console.log('div.innerText', div.innerText)
			console.log('div.textContent', div.textContent)
			div.textContent = ''
			console.log('修改后div.textContent', div.textContent)
			console.log('修改后document.textContent', document.textContent) //输出为null的情况
		</script>
	</body>
</html>

image.png 9、获取节点的属性

    <div id="app" class="div-wrapper">我是一个div</div>
    <script>
        let app = document.getElementById('app')
        console.log(app.getAttribute('id')) // app
        console.log(app.getAttribute('class')) // div-wrapper
    </script>

10、获取一个节点所有的属性,没回答上来

    <script>
        let app = document.getElementById('app')
        console.log(app.attributes)
    </script>

image.png

11、类数组对象转成数组

[...类数组]、Array.from(类数组)

传送门 类数组对象转数组的方法

12、获取节点的子元素、所有子元素

    <div id="app">
        <p>这是一个p标签</p>
        <p>这是二个p标签</p>
    </div>
    <script>
        let app = document.getElementById('app')
        console.log(app.childNodes)
    </script>

childNodes属性可以获取节点的所有子元素,但是呢,他会把换行和空格都当做子元素,所以上面代码输出的孩子长度是5,那显然是不对的,

改正的话,就需要写代码的时候不许换行和空格

    <div id="app"><p>这是一个p标签</p><p>这是二个p标签</p></div>
    <script>
        let app = document.getElementById('app')
        console.log(app.childNodes) // 长度是2
    </script>

思考💡: 元素和节点的区别是什么?

元素一定是节点,节点不一定是元素

节点包括:

整个文档是一个文档节点

每个 HTML 元素是元素节点

HTML 元素内的文本是文本节点

每个 HTML 属性是属性节点

注释是注释节点

image.png

参考:

元素和节点的区别是什么,两者的关系怎样

13、promise的特点

状态一旦确定就不会改变了

(1)Promise对象的状态不受外界影响

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

(2)Promise的状态一旦改变,就不会再变

Promise的状态一旦改变,就不会再变,任何时候都可以得到这个结果,状态不可以逆,只能由 pending变成fulfilled或者由pending变成rejected

14、代码题

let p = new Promise((resolve, reject) => {
	console.log(3)
	resolve(2)
	resolve(1)
}).then(console.log)

输出 3 2, 因为resovle(2) 已经改变状态了,之后不会在执行了

let p = new Promise((resolve, reject) => {
	console.log(3)
	resolve(2)
	console.log(4)
}).then(console.log)

输出 3 4 2 ,先执行同步任务,然后完成resolve的操作

注意❗❗:因为then里面只能执行函数,而console.log 是函数,到了这里,我产生了疑惑,我没有给 log 方法传递参数,它是怎么打印出结果呢?

原来,Promise库本身会给它带参调用,这是网上的答案

This executes the console.log only after the promise has successfully resolved (requires one function call) and implicitly pass the result of the promise to to the console.log function.

这里的then(console.log)
等同于then((res)=>{
    console.log(res);
})

15、promise 怎么捕获异常

then的第二个参数、catch方法

16、还有没有其他方法,怎么全局捕获promise的异常

通过添加监听unhandledrejection事件获取由于未处理catch的promise

其中node和浏览器都提供了相应的方法

node

process.on('unhandledRejection', function(err, promise) {

})

browser

window.addEventListener('unhandledrejection', function(event) {

});

基本使用方法如下:

// 全局捕获 Promise 异常,类似于 window.onerror

window.addEventListener('unhandledrejection', event => {

  const { reason, promise } = event

  console.log(reason, promise)

  // reason => Promise 失败原因,一般是一个错误对象

  // promise => 出现异常的 Promise 对象

 event && event.preventDefault() //通过阻止事件的默认行为,阻止控制台报错

}, false)

17、try catch 可以捕获promsie的异常吗?

答案是不可以

18、代码题

面试官通过这个代码题,来告诉我,为什么不可以捕获异常

console.log(5)
try {
    new Promise((_, reject) => {
        console.log(3)
        reject('err msg')
    }).catch(err => {
        console.log(2)
        throw err
        console.log(4)
    })
} catch (err) {
    console.log(8)
    console.log(err)
} finally {
    console.log(9)

}
console.log(10)

问输出什么?

我的回答是:5 3 2 8 err msg 9 10 当然我的回答是错误的,正确的回答是 5 3 9 10 2

因为promise抛出的异常不会被try catch 捕获

19、有没有了解过宏任务,把上面代码的宏任务说一下

20、面试官告诉不能捕获promise异常,那输出顺序是什么

5 3 9 10 2

21、async await有没有了解过?说一下他有什么特点

22、代码题

async function test() {
	return 1
}
console.log(test());

输出Promise { 1 }

23、try catch 捕获async await 的异常吗

能,确定

24、try catch 为什么可以捕获async await 但是不能捕获promise

我回答的是,try catch只能捕获宏任务的不能捕获微任务的异常

面试官接着问,try catch 为什么只能捕获宏任务的,不能捕获微任务的,提示我看上面的代码

结果,就是 try catch 执行在同步任务,但是promise的catch是微任务,try catch已经执行完成,才去执行微任务,try catch 执行在微任务之前,所以微任务抛错误try catch 一定捕获不到

25、js的数据类型

26、== 和 === 的了解

27、isNaN 了解过吗,写一个判断数字的方法

我本来以为isNaN挺简单的,结果今天学了一下,发现不是那么回事

参考:

isNaN()

isNaN函数其实等同于回答了这样一个问题:被测试的值在被强制转换成数值时会不会返回 IEEE-754​ 中所谓的“不是数值(not a number)”

function judgeNumber(x) {
   if (isNaN(x)) {
   	return '非数字'
   } else {
   	return '数字'
   }
}

28、判断一个值的类型的方法

29、说说你对作用域的理解

30、为什么需要设计块级作用域

为了解决es5存在的2个重要问题

(1)内存变量覆盖外层变量的值

    var value1 = 1
    function test() {
      console.log(value1)
      var value1 = 2
    }
    test() // undefined

(2)用来循环计数的变量泄露为全局变量

    for(var i = 0; i < 10; i++) {
      i+=1
      console.log(i) // 9
    }
    console.log('循环结束')
    console.log(i) //  10 for循环外部还可以访问i

31、对垃圾回收机制的理解

标记清除、引用计数

参考:

JavaScript 垃圾回收机制

浅谈js中的垃圾两种回收机制

32、为什么会有2种垃圾回收的方法

感觉是为了解决引用计数不能处理循环引用的问题,所以衍生出了标记清除,但是我在网络上没有找到答案。

33、代码题

构造一个循环引用

let obj1 = {}
let obj2 = {}
obj1.a = obj2
obj2.b = obj1
console.log(obj1)

34、平常是怎么搭建一个vue项目

35、解释一下跨域

36、代码题 是不是跨域

http:text1.360.com
http:text2.360.com

38、https的默认端口443 http默认端口 80

思考💡: 80 和8080 的区别?

2个端口

80 浏览器HTTP访问IP或域名的80端口时,可以省略80端口号,即访问http://baidu.com:80跟访问http://baidu.com一样的,浏览器自动处理

8080 端口是被用于WWW代理服务的,可以实现网页浏览,经常在访问某个网站或使用代理服务器的时候,会加上":8080"端口号。

另外Apache Tomcat web server安装后,默认的服务端口就是8080.

因为2个常用,所以做成了一种默契,没什么特殊的

39、导师是研究什么方向的

40、自己是研究什么方向的

41、为什么学前端

反问环节

我们部门是做什么业务的

360企业安全云