这个文章主要用来收集一些面试题目
我记得我面试的时候完全就没怎么让手写面试题的
基础 JavaScript 题目
一般来讲邪门的题目大都是 JS 题目吧
关于 this 指向的
1 2 3 4 5 6 7 8 9
| var user = { count: 1, getCount: function () { return this.count; }, }; console.log(user.getCount()); var func = user.getCount; console.log(func());
|
分析:
var func = user.getCount
这句,func
是一个返回this.count
的方法
可以理解为window.func()
可以复制到控制台里,输入window.count = 123
,执行func()
,将会输出 123
关于中括号语法取值的
1 2 3 4 5 6 7 8 9 10
| var a = {}; var b = { key: "b" }; var c = { key: "c" }; var d = [3, 4, 5]; a[b] = 123; a[c] = 345; a[d] = 333; console.log(a[b]); console.log(a[c]); console.log(a[d]);
|
分析:
中括号语法取值之前,会先toString()
一下
所以就变成了:
1 2 3 4 5
| a["[object Object]"] = 123; a["[object Object]"] = 345; a["3,4,5"] = 333;
|
关于函数 return 给了谁的迷惑问题
1 2 3 4 5 6 7 8 9 10 11 12 13
| var a = function (val, index) { console.log(index); return { fn: function (name) { return a(name, val); }, }; };
var b = a(0); b.fn(1); b.fn(2); b.fn(3);
|
分析:
执行b = a(0)
,b 被赋值为{fn: function (name) { return a(name, 0) }}
执行b.fn('val')
的时候,会返回一个对象{fn: function (name) { return a(name, 'val') }}
,这个对象没有赋值给任何变量(进垃圾桶吧你),b从未被改变
很简单的问题,迷惑了好久,都怪这个 index 语义化…
可以试试这样
1 2 3
| var q = b.fn(1); var w = b.fn(2); var e = b.fn(3);
|
经典的作用域闭包题目
红宝书上的
1 2 3 4 5 6 7 8 9 10 11 12
| for (var i = 0; i < 5; i++) { setTimeout(() => { console.log(i); }, 0); } for (let i = 0; i < 5; i++) { setTimeout(() => { console.log(i); }, 0); }
|
不要用 let, 用闭包试试
1 2 3 4 5
| for (var i = 0; i < 5; i++) { (function (j) { setTimeout(() => console.log(j), 1000); })(i); }
|
可以去书里查一查块级作用域,let 和 var 的区别
异步,事件循环,宏任务微任务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| console.log("start"); setTimeout(() => { console.log("children2"); Promise.resolve().then(() => { console.log("children3"); }); }, 0);
new Promise(function (resolve, reject) { console.log("children4"); setTimeout(function () { console.log("children5"); resolve("children6"); }, 0); }).then((res) => { console.log("children7"); setTimeout(() => { console.log(res); }, 0); });
|
思路:
浏览器先把代码看一遍,遇到直接执行的就执行(第一个宏任务)
遇到宏任务和微任务代码先按顺序扔一边
同步的执行完之后就执行微任务
微任务里面肯定有同步任务,微任务,宏任务
遇到同步任务直接解决,遇到微任务在微任务后面继续排队,遇到宏任务在宏任务后面继续排队
整体的执行顺序是:
有同步任务先解决,然后解决微任务,最后解决宏任务
以上输出结果:
1 2 3 4 5 6 7
| "start"; "children4"; "children2"; "children3"; "children5"; "children7"; "children6";
|
我觉得我没讲明白,但是我明白
我觉得应该找张纸面对面地讲,画四个圈儿分别代表主任务队列,微任务,宏任务,回调任务…
然后执行到哪儿就写一个
宏任务
- script(整体代码)
- setTimeout,setInterval
- xhr
- I/O
- UI 交互事件
微任务
Vue2 父子组件生命周期顺序
2022.3.30
今天被问到的问题:
组件的生命周期相关 现在有一对父子组件 他们一定有四个生命周期需要执行
父组件的 beforeCreate 父组件的 created 子组件的 beforeCreate 子组件的 created
这四个的执行顺序是怎样的
我一下子没有迷糊过来…. 回答错误了
正确的答案是这样的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| export default Vue.extend({ name: 'HomeView', components: { HelloWorld, }, beforeCreate() { console.log('父元素', 'beforeCreate') }, created() { console.log('父元素', 'created') }, beforeMount() { console.log('父元素', 'beforeMount') }, mounted() { console.log('父元素', 'mounted') }, });
export default Vue.extend({ name: 'HelloWorld', props: { msg: String, }, beforeCreate() { console.log('子元素', 'beforeCreate') }, created() { console.log('子元素', 'created') }, beforeMount() { console.log('子元素', 'beforeMount') }, mounted() { console.log('子元素', 'mounted') }, });
|
1 2 3 4 5 6 7 8
| 父元素 beforeCreate 父元素 created 父元素 beforeMount 子元素 beforeCreate 子元素 created 子元素 beforeMount 子元素 mounted 父元素 mounted
|
我觉得是因为在 mounted 之前,Vue 要完成组件树的构建,构建完成之后,从子组件开始依次向上渲染。所以 beforeMount 是一个分界线