那些年我们前端面试中经常被问到的题!(一)

简介: 那些年我们前端面试中经常被问到的题!

1.const的值什么时候可以修改

对于基本类型来说const定义的就是一个常量,一旦被赋值(初始化)就不可以修改。定义一个常量但是不赋值(初始化),会报错:Missing initializer in const declaration;如果修改一个常量则会报错:Assigment to constant variable。


对于数组和对象这样的引用类型来说

20180302182149939.png


发现确实被修改了,name这该怎么解释呢???实际上,const在赋值(初始化)了一个引用类型的时候,它只是保证引用类型的指针不变化,然而修改对象的属性不会变动对象的指针,所以修改一个赋值(初始化)为引用类型的const是完全被允许的。


我们尝试了一下修改const为引用类型的指针

20180302182731147.png

结果,不出意外的报错了。所以,const赋值(初始化)了一个引用类型的时候,是不可以去改变它的指针。

2.null和undefined的区别

null: Null类型,代表一个空值,也代表一个空对象指针,表示将来可能被指向某一个对象,使用typeof运算得到 “object”,所以你可以认为它是一个特殊的对象值。


undefined: Undefined类型,当一个声明了一个变量未初始化时,得到的就是undefined。

3.React性能优化

shouldComponentUpdate

react在每个组件生命周期更新的时候都会调用一个shouldComponentUpdate(nextProps, nextState)函数。它的职责就是返回true或false,true表示需要更新视图,false表示不需要,默认返回为true,即便你没有显示地定义 shouldComponentUpdate 函数。这就不难解释上面发生的资源浪费了。

无状态组件

当组件仅是接收 props,并将组件自身渲染到页面时,该组件就是一个 '无状态组件(stateless component)

高阶组件

React.addons.Perf插件来检测是否需要继续优化

3.vue/react的生命周期

4.es6的了解

es6是一个新的标准,它包含了许多新的语言特性和库,是JS最实质性的一次升级, 比如’箭头函数’、’字符串模板’、’generators(生成器)’、’async/await’、’解构赋值’、’class’等等,还有就是引入module模块的概念。


https://juejin.im/post/5b1d1fd6f265da6e410e137c

5.箭头函数

可以让this指向固定化,这种特性很有利于封装回调函数

(1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。

(2)不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错     误。

(3)不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用Rest参数代替。

(4)不可以使用yield命令,因此箭头函数不能用作Generator函数。

6.说说你对Promise的理解

Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件监听——更合理和更强大。

所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。


Promise对象有以下两个特点:

1) 对象的状态不受外界影响,Promise对象代表一个异步操作,有三种状态:Pending(进行中)、Resolved(已完成,又称 Fulfilled)和Rejected(已失败)


2) 一旦状态改变,就不会再变,任何时候都可以得到这个结果。


7.怎么理解async/await的

字面上看: async 是“异步”的简写,而 await 可以认为是 async wait 的简写。所以应该很好理解 async 用于申明一个 function 是异步的,而 await 用于等待一个异步方法执行完成。

async 起什么作用

这个问题的关键在于,async 函数是怎么处理它的返回值的!

我们当然希望它能直接通过 return 语句返回我们想要的值,但是如果真是这样,似乎就没 await 什么事了。所以,写段代码来试试,看它到底会返回什么:

async function testAsync() {
    return "hello async";
}
const result = testAsync();
console.log(result);

看到输出就恍然大悟了——输出的是一个 Promise 对象。

Promise { 'hello async' }


所以,async 函数返回的是一个 Promise 对象。

await 到底在等啥

一般来说,都认为 await 是在等待一个 async 函数完成。不过按语法说明,await 等待的是一个表达式,这个表达式的计算结果是 Promise 对象或者其它值(换句话说,就是没有特殊限定)。

async/await 帮我们干了啥

上面已经说明了 async 会将其后的函数(函数表达式或 Lambda)的返回值封装成一个 Promise 对象,而 await 会等待这个 Promise 完成,并将其 resolve 的结果返回出来。

async/await相对于promise来说,是更大的进步,promise需要.then链来解决回调问题,如果需要多个promise来组成then链,呢么书写会非常复杂就像这样:


/**
 * 传入参数 n,表示这个函数执行的时间(毫秒)
 * 执行的结果是 n + 200,这个值将用于下一步骤
 */
function takeLongTime(n) {
    return new Promise(resolve => {
        setTimeout(() => resolve(n + 200), n);
    });
}
function step1(n) {
    console.log(`step1 with ${n}`);
    return takeLongTime(n);
}
function step2(n) {
    console.log(`step2 with ${n}`);
    return takeLongTime(n);
}
function step3(n) {
    console.log(`step3 with ${n}`);
    return takeLongTime(n);
}
function doIt() {
    console.time("doIt");
    const time1 = 300;
    step1(time1)
        .then(time2 => step2(time2))
        .then(time3 => step3(time3))
        .then(result => {
            console.log(`result is ${result}`);
            console.timeEnd("doIt");
        });
}
doIt();
// c:\var\test>node --harmony_async_await .
// step1 with 300
// step2 with 500
// step3 with 700
// result is 900
// doIt: 1507.251ms

输出结果 result 是 step3() 的参数 700 + 200 = 900。doIt() 顺序执行了三个步骤,一共用了 300 + 500 + 700 = 1500 毫秒,和 console.time()/console.timeEnd() 计算的结果一致。


如果用 async/await 来实现呢,会是这样:

async function doIt() {
    console.time("doIt");
    const time1 = 300;
    const time2 = await step1(time1);
    const time3 = await step2(time2);
    const result = await step3(time3);
    console.log(`result is ${result}`);
    console.timeEnd("doIt");
}
doIt();

结果和之前的 Promise 实现是一样的,但是这个代码看起来是不是清晰得多,几乎跟同步代码一样

8.箭头函数与普通函数的区别

箭头函数:

let fun = () => {
   console.log('我是箭头函数')
}

普通函数:

function fun () {
   console.log('wishing普通函数')
}

箭头函数相当于匿名函数,并且简化了函数定义。箭头函数有两种格式,一种只包含一个表达式,连{ … }和return都省略掉了。还有一种可以包含多条语句,这时候就不能省略{ … }和return。

箭头函数是匿名函数,不能作为构造函数,不能使用new

let FunConstructor = () => {
    console.log('lll');
}
let fc = new FunConstructor();

箭头函数不绑定arguments,取而代之用rest参数…解决

function A(a){
  console.log(arguments);
}
A(1,2,3,4,5,8);  //  [1, 2, 3, 4, 5, 8, callee: ƒ, Symbol(Symbol.iterator): ƒ]
let B = (b)=>{
  console.log(arguments);
}
B(2,92,32,32);   // Uncaught ReferenceError: arguments is not defined
let C = (...c) => {
  console.log(c);
}
C(3,82,32,11323);  // [3, 82, 32, 11323]

箭头函数不绑定this,会捕获其所在的上下文的this值,作为自己的this值

var obj = {
  a: 10,
  b: () => {
    console.log(this.a); // undefined
    console.log(this); // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
  },
  c: function() {
    console.log(this.a); // 10
    console.log(this); // {a: 10, b: ƒ, c: ƒ}
  }
}
obj.b(); 
obj.c();
var obj = {
  a: 10,
  b: function(){
    console.log(this.a); //10
  },
  c: function() {
     return ()=>{
           console.log(this.a); //10
     }
  }
}
obj.b(); 
obj.c()();
相关文章
|
1月前
|
缓存 前端开发 JavaScript
"面试通关秘籍:深度解析浏览器面试必考问题,从重绘回流到事件委托,让你一举拿下前端 Offer!"
【10月更文挑战第23天】在前端开发面试中,浏览器相关知识是必考内容。本文总结了四个常见问题:浏览器渲染机制、重绘与回流、性能优化及事件委托。通过具体示例和对比分析,帮助求职者更好地理解和准备面试。掌握这些知识点,有助于提升面试表现和实际工作能力。
66 1
|
3月前
|
Web App开发 前端开发 Linux
「offer来了」浅谈前端面试中开发环境常考知识点
该文章归纳了前端开发环境中常见的面试知识点,特别是围绕Git的使用进行了详细介绍,包括Git的基本概念、常用命令以及在团队协作中的最佳实践,同时还涉及了Chrome调试工具和Linux命令行的基础操作。
「offer来了」浅谈前端面试中开发环境常考知识点
|
4月前
|
存储 XML 移动开发
前端大厂面试真题
前端大厂面试真题
|
2月前
|
Web App开发 JavaScript 前端开发
前端Node.js面试题
前端Node.js面试题
|
4月前
|
存储 前端开发 JavaScript
44 个 React 前端面试问题
【8月更文挑战第18天】
58 2
|
4月前
|
存储 JavaScript 前端开发
2022年前端js面试题
2022年前端js面试题
46 0
|
4月前
|
存储 前端开发 JavaScript
44 个 React 前端面试问题
44 个 React 前端面试问题
|
4月前
|
存储 JavaScript 前端开发
|
4月前
|
Web App开发 存储 缓存
|
4月前
|
前端开发 应用服务中间件 API
"揭秘!面试官必问:你是如何巧妙绕过跨域难题的?前端代理VS服务器端CORS,哪个才是你的秘密武器?"
【8月更文挑战第21天】在软件开发中,尤其前后端分离架构下,跨域资源共享(CORS)是常见的挑战。主要解决方案有两种:一是服务器端配置CORS策略,通过设置响应头控制跨域访问权限,无需改动前端代码,增强安全性;二是前端代理转发,如使用Nginx或Webpack DevServer在开发环境中转发请求绕过同源策略,简化开发流程但不适用于生产环境。生产环境下应采用服务器端CORS策略以确保安全稳定。
60 0