2020前端基础知识学习第二节
1.
var a = { n: 1 };
var b = a;
a.x = a = { n: 2 };
console.log(a);
console.log(b);
答案:{ n: 2 },{ n: 1, x: { n: 2 } }
分析:这里最核心的地方就是a.x运算优先级高于=,因为a.x优先级高于=,所以在a还是{ n: 1 }的时候添加了x: { n: 2 }这个属性,
因为前面b = a;使的b和a指向了同一个地址,所以b就是{ n: 1, x: { n: 2 } }。下面有更专业和更详细的解答一起学习下,
1).var a = { n: 1 };执行完,假设产生引用地址addr_1,那么此时a指向地址addr_1的。
2).var b = a;定义b指向a,也即地址addr_1。此时,无论修改b.n还是a.n都会引起另一个值的改变,应为引用了同一个地址。
3).a.x = a = { n: 2 };这句是关键,赋值顺序从右向左。成员属性访问优先级要高于=赋值操作。所以,拆解一下步骤
3.1 a持有了地址addr_1,等待给.x进行赋值
3.2 按照赋值顺序,执行{ n: 2 },此时a引用地址变为addr_2
3.3 往左继续执行,a.x引用地址{ n: 2 }
4).按照以上执行,可以得出。b指向地址addr_1,addr_1中的.x指向了addr_2
5).a指向addr_2
2.
console.log(1);
setTimeout(() => {
console.log(2);
});
process.nextTick(() => {
console.log(3);
});
setImmediate(() => {
console.log(4);
});
new Promise((resolve, reject) => {
console.log(5);
resolve();
console.log(6);
}).then(() => {
console.log(7);
});
Promise.resolve().then(() => {
console.log(8);
process.nextTick(() => {
console.log(9);
});
});
答案:1 5 6 3 7 8 9 2 4
分析:整个过程分三步来进行,
第一步script整体代码被执行,执行过程为
打印1
创建setTimeout macro-task
process.nextTick 创建micro-task
创建setImmediate macro-task
创建micro-task Promise.then 的回调,并执行console.log(5);resolve();console.log(6);此时打印5 6,虽然调用了resolve,
但是整体代码还没执行完,无法进入Promise.then流程
创建micro-task Promise.then 的回调
第一个过程之后打印出来1 5 6
第二步由于micro-task的优先级高于macro-task,此时micro-task中有三个任务按照优先级process.nextTick高于Promise
所以输出3 7 8,这是有又有新的micro-task被添加进来直接执行打印出来9
第三部micro-task任务列表已经执行完毕,接下来macro-task,由于setTimeout优先级高于setImmediate,所以打印2 4
总结:同步代码执行顺序优先级高于异步代码执行顺序优先级,new Promise(fn)中的fn是同步执行
process.nextTick() > Promise.then > setTimeout > setImmediate
3.
[‘1‘, ‘2‘, ‘3‘, ‘4‘, ‘5‘].map(parseInt)
答案:1 NaN NaN NaN NaN
分析:
参见这篇博客的详细分析https://www.cnblogs.com/typeof/p/12168571.html
4.
CSS实现九宫格布局,有多种方式可以实现九宫格布局,下面列出来比较常用的方法,
1). flex方案,比如有以下的html结构布局
<div class="square flex">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
</div>
5.
根据方法调用返回结果完成函数的实现
function add() {}
function one() {}
function two() {}
one(add(two())); // 3
two(add(one())); // 3
答案:function add(val) {
return function(val2) {
return val + val2;
}
}
function one(fn) {
let a = 1;
return typeof fn == ‘function‘ ? fn(a) : a;
}
function two(fn) {
let b = 2;
return typeof fn == ‘function‘ ? fn(b) : b;
}
6.
a11y
作为一名开发人员,你可能时常看到 “Accessibility” 这个词。在Web发展的初期,人们习惯性将其翻译成“无障碍”,
因为它的初衷主要是考虑如何让残障人士更容易地访问Web内容。比如有行动障碍的人士他更依赖于键盘与Web做交互;
有视觉障碍人士更依赖于放大屏幕与Web交互;有听力障碍人士更依赖于阅读方式等。但随着互联网的发展,
访问Web的场景、设置和人群都更复杂化,多样化。“Accessibility”已不再局限于满足残障人士的需求,
它也涵盖了在特定场景下的网站可用性,比如移动终端,弱网环境、忘带鼠标,触模板坏了,老年人访问等等。
在面对这样的新场景、新群体之下,“Accessibility”更多时候被译为可访问性。常常也被缩写为a11y(其中11是指a和y之间有11个字母)。
因此,在整个社区你会看到有很多以a11y为名的网站或应用,一般这些网站都是围绕着“Accessibility”相关的内容,
比如A11y.meThe A11Y Project和A11yWeeky等。
7.
解释一下BFC、IFC、FFC
BFC(Block Formatting Contexts)直译为“块级格式化上下文”,触发BFC的元素是一个隔离的渲染区域,容器内的子元素不会在布局上,
影响到外面的元素,外边的元素也不会影响到内部的。下面看下哪些元素会产生BFC
1) 根元素
2) float属性不为none
3) position为absolute或fixed
4) display为inline-block, table-cell, table-caption, flex
5) overflow不为visible
元素产生BFC之后的布局规则如下
内部的盒子会在垂直方向上,一个个放置
盒子垂直方向的距离由margin决定,属于同一个BFC的两个相邻Box的上下margin会发生重叠
每个元素的左边与包含它的盒子的左边相接触,即使存在浮动也是如此
BFC的区域不会与float重叠
BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之也是如此
计算BFC的高度时,浮动元素也参与计算
IFC(Inline Formatting Contexts)直译为“内联格式化上下文”
FFC(Flex Formatting Contexts)直译为“自适应格式化上下文”
8. DOCTYPE的标准模式与兼容模式各有什么区别?
标准模式用于呈现遵循最新标准的网页,兼容模式用于呈现为传统浏览器而设计的网页
标准模式的排版和js运行模式都以该浏览器支持的最高标准运行
兼容模式中,页面以宽松的向后兼容的方式显示,模拟老式浏览器的行为以防止站点无法工作
具体区别:
盒模型
严格模式下:width是内容宽度,元素真正的宽度等于width
兼容模式下:width等于width + padding + border
兼容模式下可设置百分比的高度和行内元素的高宽
在标准模式下,给span等行内元素设置wdith和height都不会生效,而在兼容模式下,则会生效
在标准模式下,一个元素的高度是由其包含的内容来决定的,如果父元素没有设置高度,子元素设置一个百分比的高度是无效的
用margin:0 auto设置水平居中在IE下会失效
使用margin:0 auto在标准模式下可以使元素水平居中,但在兼容模式下却会失效(用text-align属性解决)
body{text-align:center};#content{text-align:left}
兼容模式下Table中的字体属性不能继承上层的设置,white-space: pre会失效,设置图片的padding会失效
9.
HTML5为什么只需要写DOCTYPE html
HTML5不基于SGML(标准通用标记语言),因此不要对DTD进行引用,但是需要DOCTYPE来规范浏览器的行为(让浏览器按照他们的方式来运行)
而HTML4.0.1基于SGML,所以需要对DTD进行引用,才能告知浏览器文档所使用的文档类型
SGML(标准通用标记语言)是比HTML、XML更老的标准,这两个都是由SGML发展而来的,HTML5不是
10.
编写一个算法来判断一个数是不是“快乐数”
一个“快乐数”定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,
也可能是无限循环但始终变不到 1。如果可以变为 1,那么这个数就是快乐数
答案:
// var list = [];
var isHappy = function(num) {
num = (‘‘ + num).split(‘‘);
num = num.map(cur => Math.pow(cur, 2)).reduce((sum, cur) => {
return sum + cur;
}); // 1^2 + 9^2 = 82
if (num == 1) { // 是快乐数
return true;
}
if (num == 4) { // 不是快乐数,跳出递归来源于@墨尘大神的灵感
// if (list.includes(num)) { // 不是快乐数,跳出递归
return false;
}
// list.push(num);
return isHappy(num);
}