css
1,盒模型
2,如何实现一个最大的正方形
3,一行水平居中,多行居左
4,水平垂直居中
5,两栏布局,左边固定,右边自适应,左右不重叠
6,如何实现左右等高布局
7,画三角形
8,link @import导入css
9,BFC理解
js
1,判断 js 类型的方式
2,ES5 和 ES6 分别几种方式声明变量
3,闭包的概念?优缺点?
4,浅拷贝和深拷贝
5,数组去重的方法
6,DOM 事件有哪些阶段?谈谈对事件代理的理解
7,js 执行机制、事件循环
8,介绍下 promise.all
9,async 和 await,
10,ES6 的 class 和构造函数的区别
11,transform、translate、transition 分别是什么属性?CSS 中常用的实现动画方式,
12,介绍一下rAF(requestAnimationFrame)
13,javascript 的垃圾回收机制讲一下,
14,对前端性能优化有什么了解?一般都通过那几个方面去优化的?
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
在没有引入
let
前typeof
是绝对安全,不会出错的typeof
对于没有声明的变量会显示undefined
不会报错,但是对于未声明的变量会报错ReferenceError
总之,暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。
不允许重复声明
注意区分重复冗余声明和嵌套声明
2、块级作用域
存在意义
ES5只有全局作用域和函数作用域
解决以下场景问题:
- 内层变量可能会覆盖外层变量。
- 用来计数的循环变量泄露为全局变量。
ES6的块级作用域
let
为JavaScript新增了块级作用域。
ES6允许块级作用域的任意嵌套。
内层作用域可以定义外层作用域的同名变量。
块级作用域的出现,实际上使得获得广泛应用的**匿名立即执行函数表达式(匿名 IIFE)**不再必要了。
块级作用域与函数声明
ES5 规定,函数只能在顶层作用域和函数作用域之中声明,不能在块级作用域声明。
ES6 引入了块级作用域,明确允许在块级作用域之中声明函数。ES6 规定,块级作用域之中,函数声明语句的行为类似于let
,在块级作用域之外不可引用。
为了避免块级作用域内声明的函数的处理规则对老代码产生很大的影响,减轻不兼容问题,ES6允许浏览器有自己的行为方式,规则如下:
- 允许在块级作用域内声明函数。
- 函数声明类似于
var
,即会提升到全局作用域或函数作用域的头部。 - 同时,函数声明还会提升到所在的块级作用域的头部。
注意,上面三条规则只对 ES6 的浏览器实现有效,其他环境的实现不用遵守,还是将块级作用域的函数声明当作
let
处理。
根据这三条规则,浏览器的 ES6 环境中,块级作用域内声明的函数,行为类似于var
声明的变量。
考虑到环境导致的行为差异太大,应该避免在块级作用域内声明函数。如果确实需要,也应该写成函数表达式,而不是函数声明语句。
// 块级作用域内部的函数声明语句,建议不要使用
{
let a = 'secret';
function f() {
return a;
}
}
// 块级作用域内部,优先使用函数表达式
{
let a = 'secret';
let f = function () {
return a;
};
}
复制代码
ES6 的块级作用域必须有大括号,如果没有大括号,JavaScript 引擎就认为不存在块级作用域。
3、const命令
基本用法
const
声明一个只读的常量。一旦声明,常量的值就不能改变。
const
一旦声明变量,就必须立即初始化,不能留到以后赋值。
const
的作用域与let
命令相同:只在声明所在的块级作用域内有效。
const
命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用。
const
声明的常量,也与let
一样不可重复声明。
本质
const
实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。
对于简单数据类型,值就是保存变量的内存地址【常量】;复合数据类型,变量指向的内存地址保存的只是一个指向实际数据的指针。
const
只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。
因此使用const
声明一个对象,对象的属性是可变的,但是不能改变对象为另一个对象(不能改变指针的指向)。
冻结对象,无法改变对象属性应该使用
Object.freeze
方法。
var constantize = (obj) => {
Object.freeze(obj);
Object.keys(obj).forEach( (key, i) => {
if ( typeof obj[key] === 'object' ) {
constantize( obj[key] );
}
});
};
复制代码
ES6声明变量的六种方法
ES5
- var
- function
ES6
- let
- const
- import
- class
4、顶层对象的属性
顶层对象,在浏览器环境指的是window
对象,在 Node 指的是global
对象。
ES5 之中,顶层对象的属性与全局变量是等价的。
顶层对象的属性与全局变量挂钩带来的问题:
- 首先是没法在编译时就报出变量未声明的错误,只有运行时才能知道(因为全局变量可能是顶层对象的属性创造的,而属性的创造是动态的);
- 其次,程序员很容易不知不觉地就创建了全局变量(比如打字出错);
- 最后,顶层对象的属性是到处可以读写的,这非常不利于模块化编程。
- 另一方面,window对象有实体含义,指的是浏览器的窗口对象,顶层对象是一个有实体含义的对象,也是不合适的。
从 ES6 开始,全局变量将逐步与顶层对象的属性脱钩。
var
命令和function
命令声明的全局变量,依旧是顶层对象的属性;let
命令、const
命令、class
命令声明的全局变量,不属于顶层对象的属性。
5、globalThis
对象
JavaScript 语言存在一个顶层对象,它提供全局环境(即全局作用域),所有代码都是在这个环境中运行。
但是,顶层对象在各种实现里面是不统一的。
- 浏览器里面,顶层对象是
window
,但 Node 和 Web Worker 没有window
。 - 浏览器和 Web Worker 里面,
self
也指向顶层对象,但是 Node 没有self
。 - Node 里面,顶层对象是
global
,但其他环境都不支持。
很难找到一种方法在所有情况下都取到顶层对象,因此ES2020引入了globalThis
作为顶层对象。
关于是否存在变量提升的争议问题
在学习该部分知识时,依据的是ES6入门教程以及MDN中文文档的内容,没有过多参看其他官方文档,便断定let
和const
不存在变量提升。但经过大佬指点后拜读了mdn英文文档,文档中描述了对let
、const
和class
来说是存在变量提升的,以下做详细解释。
MDN英文文档说明存在以下三种认为是变量提升(Hositing)的行为:
【原文】Hoisting is not a term normatively defined in the ECMAScript specification. The spec does define a group of declarations as HoistableDeclaration, but this only includes function, function*, async function, and async function* declarations. Hoisting is often considered a feature of var declarations as well, although in a different way. In colloquial terms, any of the following behaviors may be regarded as hoisting:
【翻译】Hosting(变量提升)不是 ECMAScript 规范中规范定义的术语。该规范确实将一组声明定义为HoistableDeclaration,但这仅包括函数,函数*,异步函数和异步函数*声明。变量提升通常也被认为是var声明的一个特征,尽管方式不同。通俗地说,有下列行为之一,可视为变量提升:
- Being able to use a variable’s value in its scope before the line it is declared. (“Value hoisting”)
最后
四轮技术面+一轮hr面结束,学习到了不少,面试也是一个学习检测自己的过程,面试前大概复习了 一周的时间,把以前的代码看了一下,字节跳动比较注重算法,面试前刷了下leetcode和剑指offer, 也刷了些在牛客网上的面经。大概就说这些了,写代码去了~
祝大家都能收获大厂offer~
篇幅有限,仅展示部分内容
tps://bbs.csdn.net/topics/618166371)**
篇幅有限,仅展示部分内容