Javascript基础面试题目与笔记

作用域 (scope)

作用域指的是变数或函式在程式码中的有效範围,有全域和区域两种,全域的作用域是文件中的全部程式码,区域的作用域只在一个block里面

作用域链(scope chain)

在原本的作用域里没有指定的变数,于是继续往父层寻找,直到找到为止,这就是scope chain

什么是 hoisting?

hoisting的特性会出现在函式或变数上,让他们的宣告提升到作用域顶端。在变数提升的特性中,如果在宣告var变数之前使用,会出现undefined,但如果在宣告前使用let和const会因为TDZ的关係报错。在函式提升的特性中,函式表达式的提升行为会与它宣告变数的提升行为一样。

var, let, const差别

作用域。var 是global scope或functional scope,let 和const是block scope。var跟let可以被重新赋值,const不行三者都会被hoist,但只有var变数可以在被宣告前使用,const和let会因为TDZ的关係,如果在宣告变数之前就使用他们会报错

JS特别要注意的地方(型别转换与小数运算)

console.log((0.1+0.2) === 0.3)的结果是什么?

结果会是falsy,因为电脑是二进位制,电脑表示精準度有限,所以实际上小数点后面会有误差,0.1加上0.2之后不会「刚好」等于0.3

可以使用toFixed解决,设定精确到小数第一位
(0.1+0.2).toFixed(1)

falsy value
falsy value是指一个不完全是false的值,但当我们尝试将它转变成布林值时,我们会得到false。在JavaScript中,有5个falsy values,分别是0、空字串(empty string)、NaN、null及undefined。

弱型别是甚么

js是弱型别的语言,在运算前会进行型别转换,假设转换后发现有字串,就会进行字串的相加,否则就是一般的数字相加。若想都以数字计算,假设有浮点数的话,可用Number(),或假设是字串和数字混杂的话,可用parseInt();另一方面,JS在减法时会将字串转为数值,如果是 const str = "3" const num = 1 的话,会以数字做计算。Typescript是用来解决弱型别的问题

== 与===的差别在哪

两个等号是宽鬆相等,在比较时会做型别转换,假设我们把字串1==数字1,字串会被转换成数字,最后回传true。
三个等号不会进行型别转换,所以如果上面两个值去做严格相等比较,最后回传false

通常不建议用宽鬆相等,可能因为型别转换造成预期外的结果。

闭包

闭包的概念就是,当一个函数内部定义了另一个函式,即便外部函式执行完毕,内部函式依旧可以访问外部函式中的变数
const a = 1;console.log(a);const outer = () => {  let a = 1;  const inner = () => {    a += 1;    console.log(a);  };  return inner;};const result = outer();result(1);//output 2result(1);//output 3

当我们呼叫 result() 时,实际上是在执行了 inner() 函式,而 inner 函式内部的 a 变数形成了一个闭包(Closure)。每次呼叫 result(),都能继续存取并修改 a 的值,且 a 的值不会重新初始化。这是因为 a 变数被 inner 函式的作用域所捕获,使得在每次呼叫 result() 时都能累加之前a的值。

AJAX

同步与非同步、promise是什么?

同步就是按顺序执行,一行程式码执行完才会执行下一行的意思,但它有个问题,如果今天读取档案 (例如是背景图片) 的程式码在最前面,它採用同步执行而且花费超久的时间,使用者可能等很久页面还是一片空白,因为处理事件的流程被「卡住」了

非同步就是不一定要按照顺序执行,如果 JS 没有「非同步」的特性,网页可能会跑两行字,然后去拿图片资源,当图片没有完全被载入,图片后面的文字也无法出现,这对于使用者体验很糟。有了JS「非同步」的特性,网页中的文字会先完全显示出来,等图片被完全载入后再显示出来,在图片出现之前,使用者能阅读网页中的所有文字内容。

Promise是用来解决非同步事件处理,确保非同步事件完成后才继续执行其他程式码,在执行过程中可以看到三种状态,分别是pending(进行中), fulfilled(已成功),跟rejected(已失败),可以用.then()和.catch()语法去实作,更进阶的语法是finally(),代表无论promise状态无论fulfilled或rejected,都会执行finally()里面的程式码,如果网站里有设置在向后端fetch资料时出现loading效果,使用finally()能确保无论资料有无回传,都会关闭loading效果

为何有callback hell、如何解决?

原因是因为在处理非同步程式码时写太多层的callback functions,可以使用async/await 语法提升可读性

async await 是什么?

async/await 语法的操作原理和promise一样,所以也被称作Promise 的语法糖,比起Promise的写法更像同步操作。用async 关键字把函式标记为异步函式,在处理promise时加await语法,用try block和catch block分别处理资料处理成功或失败
async function getData(){try{    const res = await fetch("example-url",{method:"GET"}); const data = await res.json(); console.log(data);}catch(err){ console.log(err)}}

Axios是什么?使用它的优点为何?

缺点是要安装套件优点是语法更简洁,在写request method时可简化为 axios.get("url") ,传资料给server不需用JSON.stringify(),从server接收资料也不需要用json()就能使用完整程式码如下
//确定已经跑过 npm i axiosconst axios = require('axios');axios.get('url').then(res=>{    console.log('Data', res.data)}).catch(err=>{    console.log(err)})

传参考&传值

如果是基本型别 (Primitive type),原始变数「不会」跟着複製变数的改变而变,表现出的行为是 pass by value。

如果是物件型别,且仅针对物件的内容做改变,原始变数「会」跟着複製变数的改变而有所不同,表现出的行为结果就是 pass by reference。传参考表示变数指向的是同一个记忆体位置,修改其值就会导致共享该记忆体的其他变数一起被修改

const obj1 = { id: 1 };const obj2 = obj1;console.log(obj1 === obj2); //true  两个变数共享同个记忆体位置

但要注意以下情境

let c = {name:'Sally'}let d;d=c;c={name:'Angela'}console.log(c); // {name:'Angela'}console.log(d); // {name:'Sally'}

当我们将一个新的物件赋值给c时,实际上是创建了一个新的物件,并将它的参考赋值给了c。此时,c和d已经没有任何关係了

深浅拷贝

在 JavaScript 中,多数的预设方法和运算子进行的通常是浅拷贝。然而,有一些方法并不是 JavaScript 核心语言的一部分,而是通过函式库或框架提供的,可以执行深拷贝操作

JSON.parse() 和 JSON.stringify()
const originalObj = { a: 1, b: { c: 2 } };const deepCopiedObj = JSON.parse(JSON.stringify(originalObj));originalObj.b.c = 100;console.log(deepCopiedObj); // Output: { a: 1, b: { c: 2 } } 

深层複製需要耗费更多资源,不一定有必要。对于大多数情况来说,使用展开运算子进行浅层複製已经很够了

展开运算子

展开运算子spread(...)

使用情境

複製现有阵列:如果你想要创建一个现有阵列的複製,你可以使用展开运算符将现有阵列的元素展开到一个新阵列中。例如,const newArray = [...oldArray] 将创建一个新阵列,运用的是浅拷贝。

合併阵列:如果你想要通过合併两个或更多阵列的元素来创建一个新阵列,你可以使用展开运算符将每个阵列的元素展开到一个新阵列中。例如,const newArray = [...array1, ...array2] 将创建一个新阵列,其中包含 array1 的元素,然后是 array2 的元素。

将元素添加到阵列:如果你想要将一个或多个元素添加到现有阵列并创建一个新阵列,你可以使用展开运算符将现有阵列的元素展开到一个新阵列中,然后添加新元素。例如,const newArray = [...oldArray, newItem1, newItem2]

以上若有任何错误,都欢迎留言给我,谢谢


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章