JavaScript面试技巧
这是我的第一篇帖子/博客/文章,所以非常感谢大家的任何反馈。
这是我为准备 JavaScript 面试而整理的笔记。其中一些主题比较高级,但对于中级 JavaScript 开发人员来说却是必须掌握的。
💪 基础知识
JavaScript 是一种动态类型语言
变量的数据类型可以在运行时更改。
var justAVariable = 10;
justAVariable = "I am a string now";
/* Does not throw any error */
变量
| 范围 | 可以更新吗? | 可以重新申报吗? | |
|---|---|---|---|
| 变量 | 功能性的 | 是的 | 是的 |
| 让 | 堵塞 | 是的 | 不 |
| 常量 | 堵塞 | 不 | 不 |
数据类型
-
原始值
布尔值、字符串、数字、大整数、符号、空值、未定义
-
对象
在 JavaScript 中,除了基本类型之外的所有类型都是 Object。
== v/s ===
==仅检查值(可能发生类型强制转换)===同时检查值和类型(不进行类型强制转换)
价差操作商
- 将数组展开成元素。
-
将对象拆分成键值对。
const arr = [1, 2, 3]; const copyArr = [...arr]; // copyArr = [1, 2, 3] const sum = (a, b, c) => a + b + c; sum(...arr); // Equivalent to sum(1, 2, 3) const obj = { x: 10 }; const copyObj = { ...obj }; // copyObj = { x: 10 }
剩余参数
- 将元素合并成一个数组。
-
函数可以使用可变数量的参数进行调用。
const condense = (...params) => { return params; } console.log(condense(1, 2, 3, 4)); // prints [1, 2, 3, 4] console.log(condense(1, 2)); // prints [1, 2]
🫡 数组方法
map() 方法
arr.map((element, index, array) ⇒ { /* Modify element */ })
/* returns a new array with modified elements */
const numbers = [1, 2, 3, 4];
const double = numbers.map((ele) => ele * 2); // [2, 4, 6, 8]
filter() 方法
arr.filter((element, index, array) ⇒ { /* Condition */ })
/* returns a new array whose elements satisfy the condition */
const numbers = [1, 2, 3, 4];
const evenNumbers = numbers.filter((ele) => ele % 2 == 0); // [2, 4]
find() 方法
arr.find((element, index, array) ⇒ { /* Condition */ })
/* returns the first element satisfying the condition */
const numbers = [1, 2, 3, 4];
const greaterThanTwo = numbers.find((ele) => ele > 2); // 3
reduce() 方法
arr.reduce((prevEle, currEle, currIndex, array) ⇒ { /* Code */ }, initialVal)
/* returns a single value - the accumulated result of calling the callback function on each element */
const numbers = [1, 2, 3, 4];
const sum = numbers.reduce((prev, curr) => prev + curr, 0); // 10
☝️ 吊装
函数、变量和类的声明被移到作用域的顶部。
可变提升
-
var被提升并用 初始化undefined。console.log(a); // prints "undefined" var a = 10; -
let并且const被提升,但未被初始化。console.log(b); // ReferenceError: b is not defined let b = 20; -
未声明的变量不进行变量提升。
console.log(c); // ReferenceError: c is not defined c = 30;
功能提升
函数声明会被提升。(箭头函数不会被提升。)
helloWorld(); // Works
function helloWorld() {
console.log("Hello World");
}
等级提升
- 类声明会被提升,但不会被初始化。
⚠️ 函数表达式和类表达式不会被提升。
🤝 结束
- 函数及其词法作用域共同构成一个闭包。
- 由于闭包的存在,我们可以访问函数的外部作用域。
-
如果我们返回一个函数,即使外部函数执行完毕,它仍然会存储对外部作用域中变量和函数的引用。
function outerFunc() { let str = "Hello World"; return () => console.log(str); } const testClosure = outerFunc(); testClosure(); // prints "Hello World" /* The returned function still remembers the value of str" */ -
注意:这里只存储变量的引用,而不是实际值。因此,如果在调用返回的函数之前修改了变量,它将反映更新后的值。
let arr = []; function outerFunc() { arr.push(1); return () => console.log(arr); } const testClosure = outerFunc(); arr.push(2); testClosure(); // prints [2, 1]
😮💨 立即调用函数表达式 (IIFE)
- 没有名称 ⇒匿名 函数
-
在定义完成后立即执行。
/* Syntax */ ( **function(){}** )(); ( **function(){}**() ); ( **() => {}** )(); !**function(){}**(); +**function(){}**(); -**function(){}**(); -
用于保护数据隐私并公开特定功能。
const iife = (() => { let val = 0; return { getVal: () => val, setVal: (n) => { val = n; }, } })(); iife.setVal(10) console.log(iife.getVal());
👩👦原型继承
-
所有对象都借助原型对象继承属性。
例如,数组继承自数组原型。
-
原型对象本身也有原型。这就形成了一个原型链,最后一个对象为空。
-
原型对象:
__proto__ -
当我们尝试访问对象中的某些内容时,它首先检查该对象,然后检查其原型,然后检查原型的原型,依此类推。
const arr = []; arr.push(1); // We can acces this due to the arr.__proto__.push() method
👌 事件循环
写文章解释太费时间了😅
看看这个视频吧:
事件循环到底是什么? | Philip Roberts | JSConf EU
文章来源:https://dev.to/satejbidvai/javascript-for-interviews-4k6e