JavaScript 的事件循环
//请写出输出内容
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end');
}
async function async2() {
console.log('async2');
}
console.log('script start');
setTimeout(function() {
console.log('setTimeout');
}, 0)
async1();
new Promise(function(resolve) {
console.log('promise1');
resolve();
}).then(function() {
console.log('promise2');
});
console.log('script end');
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
具体分析看 https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/7 。
前端中的模块化开发
https://www.processon.com/view/link/5c8409bbe4b02b2ce492286a#map
Vue 的父组件和子组件生命周期钩子执行顺序是什么
加载渲染过程
- 父组件:
beforeCreate
->created
->beforeMount
- 子组件: ->
beforeCreate
->created
->beforeMount
->mounted
- 父组件: ->
mounted
- 父组件:
子组件更新过程
- 父组件:
beforeUpdate
- 子组件: ->
beforeUpdate
->updated
- 父组件: ->
updated
- 父组件:
父组件更新过程
- 父组件:
beforeUpdate
->updated
- 父组件:
销毁过程
- 父组件:
beforeDestroy
- 子组件: ->
beforeDestroy
->destroyed
- 父组件: ->
destroyed
- 父组件:
npm install
就可以自动安装对应的模块
介绍下 npm 模块安装机制,为什么输入 npm 模块安装机制:
- 发出npm install命令
- 查询node_modules目录之中是否已经存在指定模块
- 若存在,不再重新安装
- 若不存在
- npm 向 registry 查询模块压缩包的网址
- 下载压缩包,存放在根目录下的.npm目录里
- 解压压缩包到当前项目的node_modules目录
更详细的请查看: https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/22 。
kebab-case字符串与camelCase字符串互相转换
以下全部以'kebab-case'
、'kebabCase'
为例
'kebab-case'
转'kebabCase'
slice
- 第一种
function strToCamelCase(str){
let res = str.split('-').map(element => element.slice(0, 1).toUpperCase() + element.slice(1)).join('');
return res.slice(0, 1).toLocaleLowerCase() + res.slice(1);
}
strToCamelCase('kebab-case'); // "kebabCase"
1
2
3
4
5
6
2
3
4
5
6
- 第二种
function strToCamelCase(str){
let res = str.split('-').map(element => `${element.slice(0, 1).toUpperCase()}${element.slice(1)}`).join('');
return `${res.slice(0, 1).toLocaleLowerCase()}${res.slice(1)}`;
}
strToCamelCase('kebab-case'); // "kebabCase"
1
2
3
4
5
6
2
3
4
5
6
- 第三种
function strToCamelCase(str){
return `${str.slice(0, 1)}${str.slice(1).replace(/-([a-z])/g, (match, p1, offset, string) => { return p1.toUpperCase()})}`
}
strToCamelCase('kebab-case'); // "kebabCase"
1
2
3
4
5
2
3
4
5
charAt
与 slice
- 第一种
function strToCamelCase(str){
return str.split('-').map(element => element.charAt(0).toUpperCase() + element.slice(1)).join('');
}
strToCamelCase('kebab-case'); // "kebabCase"
1
2
3
4
5
2
3
4
5
- 第二种
function strToCamelCase(str){
return `${str.charAt(0)}${str.slice(1).replace(/-([a-z])/g, (match, p1, offset, string) => { return p1.toUpperCase()})}`
}
strToCamelCase('kebab-case'); // "kebabCase"
1
2
3
4
5
2
3
4
5
substring
function strToCamelCase(str){
return str.split('-').map(element => element.substring(0, 1).toUpperCase() + element.substring(1)).join('');
}
strToCamelCase('kebab-case'); // "kebabCase"
1
2
3
4
5
2
3
4
5
substr
function strToCamelCase(str){
return str.split('-').map(element => element.substr(0, 1).toUpperCase() + element.substr(1)).join('');
}
strToCamelCase('kebab-case'); // "kebabCase"
1
2
3
4
5
2
3
4
5
'kebabCase'
转'kebab-case'
function strToKebabCase(str){
return str.replace(/([A-Z])/g, (match, p1, offset, string) => { return `-${p1.toLowerCase()}` })
}
strToKebabCase('kebabCase'); // "kebab-case"
1
2
3
4
5
2
3
4
5
时间格式化
时间格式转换,第一个参数接受的时间格式字符串,第二个参数可以传入一个时间点或者不传(当前时间)。
function dateFormat(format, date){
let addZero = (num) => { return num < 10 ? `0${num}` : num },
now = date ? new Date(date.replace(/-/g, '/')) : new Date(),
res = format;
if(format.indexOf('YYYY') > -1) res = res.replace('YYYY', now.getFullYear())
if(format.indexOf('MM') > -1) res = res.replace('MM', addZero(now.getMonth() + 1))
if(format.indexOf('DD') > -1) res = res.replace('DD', addZero(now.getDate()))
if(format.indexOf('hh') > -1) res = res.replace('hh', addZero(now.getHours()))
if(format.indexOf('mm') > -1) res = res.replace('mm', addZero(now.getMinutes()))
if(format.indexOf('ss') > -1) res = res.replace('ss', addZero(now.getSeconds()))
if(format.indexOf('day') > -1) res = res.replace('day', now.getDay())
return res;
}
dateFormat('YYYY'); // '2019'
dateFormat('YYYY-MM'); // '2019-03'
dateFormat('YYYY-MM-DD'); // '2019-03-10'
dateFormat('YYYY-MM-DD hh:mm:ss'); // '2019-03-10 15:03:10'
dateFormat('YYYY-MM-DD hh:mm:ss day'); // '2019-03-10 15:03:10 0'
dateFormat('YYYY-MM-DD hh:mm:ss day', '2019-3-8'); // '2019-03-08 00:00:00 5'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
this
a = 5;
function foo(){
console.log(this.a);
}
let obj = {
a: 2,
foo: foo
}
let bar = obj.foo;
foo()
obj.foo()
bar()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
上面console依次打印的结果: 5 2 5。
具体原因可以查看此处:https://github.com/yygmind/blog/issues/20 。
闭包
页面中有5个按钮,依次为每个按钮绑定事件,点击按钮打印出它是第几个按钮,代码如下:
var buttons = document.getElementsByTagName('button');
for(var i = 0; i < buttons.length; i++) {
buttons[i].onclick = function() {
console.log(i);
}
}
1
2
3
4
5
6
2
3
4
5
6
请问按钮点击输出的内容是什么?你对这段代码怎么优化?
**答案:**每个按钮点击输出的都是 5 。 对于此段代码的优化:
var buttons = document.getElementsByTagName('button');
for(var i = 0, len = buttons.length; i < len; i++) {
(function(i){
buttons[i].onclick = function() {
console.log(i);
}
})(i);
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
或者是全部使用let。
let buttons = document.getElementsByTagName('button');
for(let i = 0, len = buttons.length; i < len; i++) {
buttons[i].onclick = function() {
console.log(i);
}
}
1
2
3
4
5
6
2
3
4
5
6
上面这个题让我想到了之前看到的一道题,请问下面代码输出的内容是:
for(var i = 0; i < 5; i++) {
setTimeout(function(){
console.log(i)
}, 0);
}
1
2
3
4
5
2
3
4
5
输出的都是 5 。那怎么可以延迟输出0,1,2,3,4呢?
可以这样:
for(var i = 0; i < 5; i++) {
(function(i){
setTimeout(function(){
console.log(i)
}, 0);
})(i)
}
1
2
3
4
5
6
7
2
3
4
5
6
7
或者:
for(let i = 0; i < 5; i++) {
setTimeout(function(){
console.log(i)
}, 0);
}
1
2
3
4
5
2
3
4
5