百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

那些陌生又熟悉的前端面试题(经典前端面试题)

wxin55 2024-11-17 02:44 8 浏览 0 评论

过完年需要跳槽的小伙伴还是挺多的,又要开始刷前端面试题了!会不会有一种错觉,看着这道面试题很熟,但是不知道该如何做?或者有答案又不知道是否正确?或者使用编辑器可以运行出来正确的答案,但是不知道怎么得来的,这些你都中招了吗?

如果你也是这样,关注前端人,分享更多面试题、答案及知识点详解!

1、严格模式与非严格模式的区别,你了解多少?

JavaScript 语言是一门弱类型语言,存在许多类型错误,因此 ES6 引入了严格模式概念。

如果不加 ‘use strict’ 常规模式下就是属于非严格模式。

严格模式

在 js 文件顶部添加 ‘use strict’ 就属于严格模式,严格模式也可以指定在函数内部。

<script>
 'use strict'  
 //或者函数内部
 (function(){
  'use strict'
 })()
</script>

严格模式,是为 js 定义来了一种不同的解析与执行模型,在严格模式下,ECMAScipt 3 中一些不解和不确定的行为将得到处理,而且会对不安全的操作会抛出异常。‘use strict’ 会告诉浏览器引擎可以切换到严格模式执行。

严格模式与非严格模式区别

严格模式

非严格模式

变量必须声明才能赋值

变量不进行声明,可直接赋值

不能使用 delete 字符删除变量或对象

可以使用 delete 删除

函数参数变量名不允许重复

变量名重复,获取最后最后那个值

普通函数内的 this 为 undefined

普通函数内的 this 为 window

不允许使用八进制

允许任意进制

eval 和 arguments 当做关键字,不能被赋值和用作变量名

可以使用 eval 、arguments 作为变量名

call、apply 传入 null undefined 保持原样不被转为window

默认转为 window 对象

限制对调用栈的检测能力,访问 arguments.callee 会抛出异常

arguments.callee 运行正常

2、深浅拷贝的区别有哪些?

常见笔试题:

var person = {
 name:"前端人",
 hobby:['学习','敲代码','潜水']
}
function copy(source){
 var newObj = new Object()
 for(var i in source){
  if(source.hasOwnProperty(i)){
   newObj[i] = source[i]
   }
  }
 return newObj
}
var p1 = copy(person);
p1.name = "Web Person"
console.log(person.name)
console.log(p1.name)
p1.hobby = ["内卷"]
console.info(person.hobby)
console.info(p1.hobby)
/*运行结果:
前端人
 Web Person
["学习", "敲代码", "潜水"]
["内卷"]
*/

试试这道笔试题你会做吗?

要说 js 的深浅拷贝,就不得不提 js 的两大数据类型:基本数据类型和引用类型。

基本数据类型的变量名和值都存储在栈中,对于引用类型的变量名存储在栈中,而值存储在堆中。由于存储方式不同,所以导致了他们复制的时候方式不同。

赋值

基本数据类型赋值的时候,创建的基本数据类型会在内存中开辟一个新空间把值复制过来,而引用类型采用的是地址存储,如果直接把一个引用数据直接赋值给另外一个数据,就相当于直接把自己存储值的地址给了另外一个变量,所以改变一个的值,也会改变另外一个的值。

var a = 1;
var b = a;
b=2;
console.log(a) //1
console.log(b)//2
var p1 = {name:"前端人"}
var p2 = p1
p2.name = "打工仔"
console.log(p1.name) // '打工仔'
console.log(p2.name) // '打工仔'

深浅拷贝是如何定义的?

假设有 p 和 copyP 两个变量,如果copyP 是拷贝了 p 的,我们通过修改 copyP 来观察 p 是否发生改变,如果跟着改变,就是浅拷贝,如果是不改变,就说明是深拷贝。

基本类型复制的时候会开辟新的内存空间,所以两个值是相互独立的,引用类型复制的时候就要看是复制的内存地址还是复制一个新的堆。所以深拷贝主要针对的是引用类型的数据。

浅拷贝的常见的方式:

1、直接赋值

var arr1 = [1,2,3,4];
var arr2 = arr1;

2、Object.assign

var obj = {
 a:1,
 b:2
}
var o = Object.assign(obj)

深拷贝的常见方式:

引用数据类型最常用的就是 Object 和 Array ,引用数据内部的数据也可以是多样化的,进行深拷贝时,也要适当地根据数据结构进行合适的复制方式,具体的深拷贝方法分别有:

1、数组中只包含基本数据类型

  • 循环数组,将数组的值复制出来放入另一个新数组中
  • 利用 slice 方法
  • 借助 concat 方法
  • 利用 from 方法
  • 使用扩展符 ...

2、对象中只包含基本数据类型

  • 利用 for in 循环,将对象的值拿出来
  • 使用 Object 复制给一个新的空对象
  • 使用 ... 扩展运算符
  • 手动复制,将属性值一个一个单独复制

3、对象或数组里含有一层或多层引用数据类型时

  • 使用 jQuery 的 extend 方法
  • JSON.parse(JSON.stringify())
  • 使用递归自己写一个深拷贝的方法

深浅拷贝的常见应用主要是数据的增删改操作。

3、this 的指向

大厂笔试题:

var name = 'window name'
var p1 = {
 name:'p1 name',
 showName:function(){
  console.info(this.name)
 }
}
var fn = p1.showName
fn()
p1.showName()
var p2 = {
 name:'p2 name',
 showName:function(fun){
  fun()
 }
}
p2.showName(p1.showName)
p2.showName = p1.showName
p2.showName()
/*
运行结果:
window name
 p1 name
 window name
 p2 name
*/

这是一道关于 this 指向的面试题,接下来我们就说说 this 是如何指向的?

this 对象是运行时基于函数的执行环境绑定的:

  • 在全局函数中,this 等于 window 。
  • 函数上下文调用,严格模式下 this 为 undefined ,非严格模式下,this 指向 window 。
  • 当函数被作为某个对象的方法被调用时,this 等于那个对象。如果使用 call apply 改变当前 this 时,将会指向为传递过来的那个 this 。
  • 匿名函数的执行环境具有全局性,因此 this 指向 window。
  • 构造函数内的 this 指向创建的实例对象。
  • dom 事件处理函数,this 指向触发该事件的元素。
  • setTimeout 和 setInterval 中的 this 指向全局变量 window

看完上述 this 指向解释,你就可以做上边的那道面试题了。

如何改变 this 的指向?

call 、bind 和 apply 这三个函数都是用来改变 this 指向的,就是改变函数执行时的上下文。

修改上述面试题:

var name = 'window name'
var p1 = {
 name:'p1 name',
 showName:function(){
  console.info(this.name) // p2 name
 }
}
var p2 = {
 name:'p2 name',
}
p1.showName.call(p2)
p1.showName.apply(p2)
var bind = p1.showName.bind(p2)
bind()

call 、bind 和 apply 改变 this 指向,最大作用就是实现代码复用。

至于 call、bind 和 apply 的区别,可以自行去了解下。

4、隐式转化

console.log( '2'>10 ) //false
console.log( '2'>'10' ) //true
console.log( 'abc'>'b' ) //false
console.log( 'abc'>'aab' ) //true
console.log( undefined == null ) //true
console.log( NaN == NaN )//false
console.log( [] == 0 ) //true
console.log( ![] == 0 ) //true
console.log( [] == [] ) //false
console.log( {} == {} ) //false
console.log( {} == !{} ) //false

对象的类型转换表

有了上边那个表,事情就变得简单了!

关系运算符进行运算时,不同类型的值会自动转化为相同类型值,然后进行

1、两边有一个是字符串一个是是数字时,字符串调用 Number 方法,将字符串转为数字,所以:

console.log( '2'>10 )  => console.log( 2>10 ) 

2、如果两边都是字符串时,按照字符串的 unicode 编码来转换的,所以:

'2'.charCodeAt() = 50
'10'.charCodeAt() = 49
console.log( '2'>'10' ) => console.log( 50 >49 )

3、字符串进项比较时,先比较第一位,如果不相等直接得出结果,如果第一项相等,会继续使用第二项进行比较。

console.log( 'abc'>'b' ) // a < b 所以为 false
console.log( 'abc'>'aab' ) // a=a 第二位 b>a 所以为 true

4、转为布尔值都为 false 的类型分别有:undefined 、null 、0、NaN、false、‘’

console.log( undefined == null ) //true

5、NaN表示的是非数字,但是这个非数字也是不同的,因此 NaN 不等于 NaN,两个NaN永远不可能相等。

console.log( NaN == NaN )//false


6、关系运算有一个数值,将另外一个值也转为 number 类型。

Number([].valueOf().toString()) = 0
console.log( [] == 0 ) => console.log( 0 == 0 ) //true

7、有逻辑运算的,将其他数据类型转为 boolean 值。

Boolean([]) = true => 取反 true
console.log( ![] == 0 ) => console.log( false == false ) //true

8、直接使用两个空数组比较,数组地址不同,所以不相等。

console.log( [] == [] ) //false
// 对象地址不一样
console.log( {} == {} ) //false
{}.valueOf().toString() ="[object Object]"
console.log( {} ==

评论区可以留下最近你想学习的知识点,或面试题类型!

相关推荐

ES6中 Promise的使用场景?(es6promise用法例子)

一、介绍Promise,译为承诺,是异步编程的一种解决方案,比传统的解决方案(回调函数)更加合理和更加强大在以往我们如果处理多层异步操作,我们往往会像下面那样编写我们的代码doSomething(f...

JavaScript 对 Promise 并发的处理方法

Promise对象代表一个未来的值,它有三种状态:pending待定,这是Promise的初始状态,它可能成功,也可能失败,前途未卜fulfilled已完成,这是一种成功的状态,此时可以获取...

Promise的九大方法(promise的实例方法)

1、promise.resolv静态方法Promise.resolve(value)可以认为是newPromise方法的语法糖,比如Promise.resolve(42)可以认为是以下代码的语...

360前端一面~面试题解析(360前端开发面试题)

1.组件库按需加载怎么做的,具体打包配了什么-按需加载实现:借助打包工具(如Webpack的require.context或ES模块动态导入),在使用组件时才引入对应的代码。例如在V...

前端面试-Promise 的 finally 怎么实现的?如何在工作中使用?

Promise的finally方法是一个非常有用的工具,它无论Promise是成功(fulfilled)还是失败(rejected)都会执行,且不改变Promise的最终结果。它的实现原...

最简单手写Promise,30行代码理解Promise核心原理和发布订阅模式

看了全网手写Promise的,大部分对于新手还是比较难理解的,其中几个比较难的点:状态还未改变时通过发布订阅模式去收集事件实例化的时候通过调用构造函数里传出来的方法去修改类里面的状态,这个叫Re...

前端分享-Promise可以中途取消啦(promise可以取消吗)

传统Promise就像一台需要手动组装的设备,每次使用都要重新接线。而Promise.withResolvers的出现,相当于给开发者发了一个智能遥控器,可以随时随地控制异步操作。它解决了三大...

手写 Promise(手写输入法 中文)

前言都2020年了,Promise大家肯定都在用了,但是估计很多人对其原理还是一知半解,今天就让我们一起实现一个符合PromiseA+规范的Promise。附PromiseA+规范地址...

什么是 Promise.allSettled()!新手老手都要会?

Promise.allSettled()方法返回一个在所有给定的promise都已经fulfilled或rejected后的promise,并带有一个对象数组,每个对象表示对应的pr...

前端面试-关于Promise解析与高频面试题示范

Promise是啥,直接上图:Promise就是处理异步函数的API,它可以包裹一个异步函数,在异步函数完成时抛出完成状态,让代码结束远古时无限回掉的窘境。配合async/await语法糖,可...

宇宙厂:为什么前端离不开 Promise.withResolvers() ?

大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发。1.为什么需要Promise.with...

Promise 新增了一个超实用的 API!

在JavaScript的世界里,Promise一直是处理异步操作的神器。而现在,随着ES2025的发布,Promise又迎来了一个超实用的新成员——Promise.try()!这个新方法简...

一次搞懂 Promise 异步处理(promise 异步顺序执行)

PromisePromise就像这个词的表面意识一样,表示一种承诺、许诺,会在后面给出一个结果,成功或者失败。现在已经成为了主流的异步编程的操作方式,写进了标准里面。状态Promise有且仅有...

Promise 核心机制详解(promise机制的实现原理)

一、Promise的核心状态机Promise本质上是一个状态机,其行为由内部状态严格管控。每个Promise实例在创建时处于Pending(等待)状态,此时异步操作尚未完成。当异步操作成功...

javascript——Promise(js实现promise)

1.PromiseES6开始支持,Promise对象用于一个异步操作的最终完成(包括成功和失败)及结果值的表示。简单说就是处理异步请求的。之所以叫Promise,就是我承诺,如果成功则怎么处理,失败怎...

取消回复欢迎 发表评论: