箭头函数和普通函数的区别
普通函数: this指向运行时所在的对象
箭头函数:
- 箭头函数没有自己的this对象,内部的this就是定义时上层作用域的this对象,所以箭头函数的this指向是固定的,普通函数的this是可变的(所以箭头函数可以用来固定this指向)
- 箭头函数不能用做构造函数,用new实例化时会报错,*** is not a constructor
- 不能用arguments,因为在函数体内没有这个对象,可以用解构rest来代替,箭头函数也没有super,new.target
- 内部不能用yield命令,不能用做generator函数
先.then再.finally 跟 先.finally后.then有啥区别?
动手写个demo
const flag = true;
function funcPromise() {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (flag) {
resolve('2秒时间到, 一切正常')
} else {
reject('时间到了,失败了!')
}
}, 2000);
})
}
funcPromise().then(res => {
console.log('res', res);
}).finally(response => {
console.log('response', response);
}).catch(err => {
console.log('err', err);
})
finally方法是不管promise方法执行后的结果是什么,都会执行的,内部其实也是调用了then方法。
且finally后仍可以跟then方法,还会把结果原封不动的传递给紧跟的then方法(不管结果是resolve或者reject)。
所以先then后finally,then接受的结果是前一个promise方法的。
先finally后then,then接受的结果是从finally里传递出来的。
Promise.prototype.finally = function (callback) {
return this.then((value) => {
return Promise.resolve(callback()).then(() => {
return value;
});
}, (err) => {
return Promise.resolve(callback()).then(() => {
throw err;
});
});
}
什么情况下position: fixed定位会失效?
position:fixed是相对于视口来定位,并且元素的位置在屏幕滚动时不会变化。
当元素祖先的 transform 属性非 none 时,容器由视口改为该祖先。即如果fixed的组件设置了transform值(不为none)后,那么fixed定位就是相对于该祖先了。
因为transform会创建一个堆叠上下文(Stacking Context)和包含块(Containing Block),由于堆叠上下文的创建,该元素会影响其子元素的固定定位
堆叠上下文是HTML元素的三维概念,这些HTML元素在一条假想的相对于面向(电脑屏幕的)视窗或者网页的用户的 z 轴上延伸,HTML 元素依据其自身属性按照优先级顺序占用层叠上下文的空间。
另外:
子元素的 z-index 值只在父级层叠上下文中有意义。意思就是父元素的 z-index 低于父元素另一个同级元素,子元素 z-index再高也没用。
为什么在写jsx时没有显式的使用react,但依然要引入react
本质上来说JSX是React.createElement(component, props, ...children)
方法的语法糖。
如果使用了jsx其实就是使用了React
例如:
const title = <h1 className="title">Hello, world!</h1>;
并不是一段合法的代码,是一种被成为jsx的语法扩展,方便我们在js里写html片段,最终会被babel转译为以下代码
const title = React.createElement(
'h1',
{ className: 'title' },
'Hello, world!'
);
所以如果用了jsx语法,需要引入React,否则编译后无法运行。
es2020知识点
Q:
// x最终返回值是什么??
var obj = {};
var x = +obj.hyy?.name ?? 'hello world!';
console.log(x);
A:
NAN
解析:
?是链判断运算符,如果值不存在,则返回undefined;
??是如果左侧是null或者undefined则返回右侧的值,否则返回左侧值;
+转成数字;如果不是数字返回NaN。
所以最终就是:+undefined ?? ‘hello world!’ 即 NaN ?? ‘hello world!’
数组相关
Q:
// 以下代码打印结果是什么
const arr1 = ['a', 'b', 'c'];
const arr2 = ['c', 'b', 'a'];
console.log(
arr2.sort() === arr2,
arr1.sort() === arr1,
arr1.sort() === arr2.sort()
)
A:
true, true, false;
数组的sort方法是对原数组直接修改,返回对该数组的引用;
sort前和sort后数组的引用指向的是同一块内存
果然做不到一天一道题,高估我自己了 -_-|||
关于解构
Q:
let hObject = { ...null, ...undefined };
console.log(hObject);
let hArray = [...null, ...undefined];
console.log(hArray);
A:
{}
抛出异常 Uncaught TypeError: object null is not iterable (cannot read property Symbol(Symbol.iterator))
对象解构时会忽略null和undefined,数组是执行interable的next方法
关于dom解析
Q: 以下两行文字是什么颜色?
<style>
.red {
color: red
}
.blue {
color: blue;
}
.green {
color: green
}
</style>
<div class="red blue">1.我是什么颜色?</div>
<div class="green blue red">2.我又是什么颜色呢?</div>
A:
- 蓝色
- 绿色
css样式表关联到dom节点后,css样式按照声明顺序生效,先是红色,然后蓝色,最后绿色
运算
Q: 以下代码打印结果是什么?
console.log(1<2<3);
console.log(3>2>1);
A:
true false
<,>的运算顺序,从左往右;
1<2返回true,true < 3会隐式类型转换成1<3,最后返回true
3>2同理也是返回true, true < 1转换成1<1,最后返回false
-----半个月没博学了------
作用域
Q:以下代码执行结果
function foo () {
console.log(length);
}
function bar() {
var length = '23454';
foo();
}
bar();
A:
0 (window.length 即 iframe的数量)
JavaScript 语言的作用域链是由词法作用域决定的,而词法作用域是由代码结构来确定的
实现 Promise.retry,成功后 resolve 结果,失败后重试,尝试超过一定次数才真正的 reject
// 实现一个Promise.retry方法,可以重新执行方法,直到n次后才执行reject
Promise.retry = async (callback, times) => {
let count = 0;
let error = new Error();
while(count <= times) {
try {
const result = await callback.call(this);
return result;
} catch (err) {
error = new Error(err);
count++;
continue;
}
}
throw error;
}
function testFunc() {
let n = 1;
return () => {
return new Promise((resolve, reject) => {
if (n < 6) {
reject('执行错误,数字小于6');
n++
} else {
resolve(n);
}
})
}
}
Promise.retry(testFunc(), 6).then(res => {
console.log('执行成功,结果是:', res);
}).catch(err => {
console.log('执行错误,结果是:', err);
});