Shopee一面总结

分为CSS、JS、编程题
问答题目
1 块元素和行内元素的区别
块级元素特点:
(1) 总是从新行开始。
(2) 高度,行高,padding和margin都可以控制。
(3) 宽度默认是容器的100%。
(4) 可以容纳行内元素和其他块元素。
行内元素的特点:
(1) 和相邻行内元素在同一行上。
(2) 高度、宽度无效,但水平方向上的padding和margin可以设置,垂直方向无效。
(3) 默认宽度就是本身内容的宽度。
(4) 只能容纳文本或者其他行内元素。

2 讲一讲BFC
(1) 元素条件:不是所有的元素模式都能产生BFC,w3c 规范: display 属性为 block, list-item, table 的元素,会产生BFC。
(2) 触发条件:

  • float属性不为none
  • position为absolute或fixed
  • display为inline-block, table-cell, table-caption, flex, inline-flex
  • overflow不为visible。
    (3) BFC布局规则特性:
  • 在BFC中,盒子从顶端开始垂直地一个接一个地排列.
  • 盒子垂直方向的距离由margin决定。属于同一个BFC的两个相邻盒子的margin会发生重叠
  • 在BFC中,每一个盒子的左外边缘(margin-left)会触碰到容器的左边缘(border-left)(对于从右到左的格式来说,则触碰到右边缘)。
    BFC的区域不会与浮动盒子产生交集,而是紧贴浮动边缘。
    计算BFC的高度时,自然也会检测浮动或者定位的盒子高度。
    (4) 用途
    清除内部浮动、解决外边距合并、自适应

3 JS中基本数据类型 如何判断数据类型
Number、String、Boolean、Null、Undefined typeof

4 讲讲闭包 什么时候需要用到闭包
闭包就是能够读取其他函数内部变量的函数,由于在 Javascript 语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成 “定义在一个函数内部的函数”。
所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
闭包的用途:

  • 可以在函数内部读取函数外部成员
  • 让函数内成员始终存活在内存中

5 ES6中let和var的区别
参考https://www.cnblogs.com/fly_dragon/p/8669057.html
(1) ES6可以用let定义块级作用域变量
在ES6之前,我们都是用var来声明变量,而且JS只有函数作用域和全局作用域,没有块级作用域,所以{}限定不了var声明变量的访问范围。
例如:

{ 
  var i = 9;
} 
console.log(i);  // 9
ES6新增的let,可以声明块级作用域的变量。
{ 
  let i = 9;     // i变量只在 花括号内有效!!!
} 
console.log(i);  // Uncaught ReferenceError: i is not defined

(2) let 配合for循环的独特应用
let非常适合用于 for循环内部的块级作用域。JS中的for循环体比较特殊,每次执行都是一个全新的独立的块作用域,用let声明的变量传入到 for循环体的作用域后,不会发生改变,不受外界的影响。看一个常见的面试题目:

for (var i = 0; i <10; i++) {  
  setTimeout(function() {  // 同步注册回调函数到 异步的 宏任务队列。
    console.log(i);        // 执行此代码时,同步代码for循环已经执行完成
  }, 0);
}
// 输出结果
10   共10个
// 这里面的知识点: JS的事件循环机制,setTimeout的机制等
如果把 var改成 let声明:

// i虽然在全局作用域声明,但是在for循环体局部作用域中使用的时候,变量会被固定,不受外界干扰。
for (let i = 0; i < 10; i++) { 
  setTimeout(function() {
    console.log(i);    //  i 是循环体内局部作用域,不受外界影响。
  }, 0);
}
// 输出结果:
0  1  2  3  4  5  6  7  8 9

(3) let没有变量提升与暂时性死区
用let声明的变量,不存在变量提升。而且要求必须 等let声明语句执行完之后,变量才能使用,不然会报Uncaught ReferenceError错误。
例如:

console.log(aicoder);    // 错误:Uncaught ReferenceError ...
let aicoder = 'aicoder.com';
// 这里就可以安全使用aicoder

ES6 明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。总之,在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。

(4) let变量不能重复声明
let不允许在相同作用域内,重复声明同一个变量。否则报错:Uncaught SyntaxError: Identifier ‘XXX’ has already been declared
例如:

let a = 0;
let a = 'sss';
// Uncaught SyntaxError: Identifier 'a' has already been declared

代码题目
(1) Promise
(2) 原型 prototype和__proto__
参考 https://juejin.im/post/5cf646466fb9a07eb3096802
(3) this.name不同情况下输出 涉及闭包、箭头函数、setTimeout
参考 https://www.jianshu.com/p/21a16d44f150
https://juejin.im/entry/58b45c348fd9c50063e50d90
(4) 多维数据转一维数组 元素可能是字符串、数字、数组等

var arr = [1, [2, [[3, 4], 5], { a: 6 }]]
var newArr = []

function fun(arr) {
  for (var i = 0; i < arr.length; i++) {
    if (Array.isArray(arr[i])) {
      fun(arr[i])
    } else {
      newArr.push(arr[i])
    }
  }
}
fun(arr)
console.log(newArr)

(5) 大正整数相加
参考 https://www.jianshu.com/p/c51d63028371
https://segmentfault.com/a/1190000003731938

function sumBigNumber(a, b) {
  var res = '',
    temp = 0;
  a = a.toString().split('');
  b = b.toString().split('');
  while (a.length || b.length || temp) {
    temp += ~~a.pop() + ~~b.pop()
    res = temp % 10 + res
    temp = temp > 9
  }
  return res.replace(/^0+/, '');
}

讲解:最巧妙的地方在于temp的值转换,既可以作为boolean值判断是否进位,也可以转为Number值,作为1加到需要进位的地方。~~两个按位取反操作符用于把字符串转为数字,pop()用于弹出数组最后一个元素。

总结
对于CSS、JS基础这一块,面试前一定要过一遍总结文档,不能忽视最基础的数据类型等方面。对于JS高级这一块,比如闭包、原型,要反复看高级程序设计这本书对应章节,并且做题练习,有所输出。对于编程这一块,只能多刷题来训练思维。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值