前端面试题整理一波

本文深入探讨前端领域的核心概念,如精度问题的解决、闭包的理解、JSONP原理、ES6新特性、Promise处理异步、事件加载差异及数据类型判断技巧。通过详细解析,帮助读者掌握前端开发的关键知识点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2020年的开头并不是很好啊,想要跳槽是难上加难。整理一波面试题就当是巩固自己的只是积累了。

js
1.前端如何解决精度问题

前端的精度问题经典案例就是0.1+0.2 = 0.30000000000000004
出现的原因:在计算机角度,计算机算的是二进制,而不是十进制。二进制后变成了无线不循环的数,而计算机可支持浮点数的小数部分可支持到52位,所有两者相加,在转换成十进制,得到的数就不准确了,加减乘除运算原理一样。
如何解决:

  1. 首先再要求不是很精确的情况下可以使用toFixed()指定要保留的小数位数,或者Math.round(x)来进行四舍五入。
  2. 将浮点数转换为整数后在转换成浮点数,例如(0.1*10+0.2*10)/10
  3. 其他可自己查阅
2.闭包
  • 什么是闭包?
    闭包就是能够读取其他函数内部变量的函数。由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成"定义在一个函数内部的函数"。所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。

  • 闭包带来的影响
    闭包有两个最大的用处,一个是可以在全局作用域中读取内部函数的的变量,另一个就是可以让闭包中引用的变量始终保存在内存中。这句话很重要了,这样垃圾回收机制就不会释放掉这些内存,这样的后果就是造成内存泄露,所以在使用完闭包后要及时把变量清掉

题外话:这个时候也许会问你还有那些操作会造成内存泄露?

  1. 计时器或回调函数
  2. 以外的全局变量
  3. dom清空或删除时,事件未清除导致的内存泄漏

再插一个题外话:能说说什么垃圾回收机制吗?
可以查阅这篇文章点击查看

3.jsonp的原理

jsonp是为了解决前端跨域问题的一种解决方案,是一种非正式的传输协议。
这里先了解一下什么的跨域:跨域是指一个域下的文档或脚本要去访问另一个域下的内容。
在了解一下同源策略:同源策略/SOP(Same origin policy)是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。
在js中img标签和script标签是不受同源策略影响的,所以jsonp就是利用

<script>
    var script = document.createElement('script');
    script.type = 'text/javascript';

    // 传参一个回调函数名给后端,方便后端返回时执行这个在前端定义的回调函数
    script.src = 'http://www.domain2.com:8080/login?user=admin&callback=handleCallback';
    document.head.appendChild(script);

    // 回调执行函数
    function handleCallback(res) {
        alert(JSON.stringify(res));
    }
 </script>
4. es6定义变量的方法

es5定义变量的方法有两种一个是var、一个是function
es6定义变量的方法有六种,除了varfunction之外,还有let、const 、import、class

  1. var命令
var a // undefined
var b = 1
  • var定义的变量可以修改,如果不初始化会输出undefined,不会报错 var声明的变量在window上,用let或者const去声明变量,这个变量不会被放到window上
  • 很多语言中都有块级作用域,但JS没有,它使用var声明变量,以function来划分作用域,大括号“{}”却限定不了var的作用域,因此用var声明的变量具有变量提升的效果
  • var 声明的变量作用域是全局的或者是函数级的
  1. function命令
  • 声明了一个名为 add的新变量,并为其分配了一个函数定义 {}之间的内容被分配给了 add
  • 函数内部的代码不会被执行,只是存储在变量中以备将来使用
  1. const命令
  • const定义的变量不可以修改,而且必须初始化
  • 该变量是个全局变量,或者是模块内的全局变量
  • 如果一个变量只有在声明时才被赋值一次,永远不会在其它的代码行里被重新赋值,那么应该使用const,但是该变量的初始值有可能在未来会被调整(常变量)
  • 创建一个只读常量,在不同浏览器上表现为不可修改;建议申明后不修改;拥有块级作用域
  • const 代表一个值的常量索引 ,也就是说,变量名字在内存中的指针不能够改变,但是指向这个变量的值可能 改变
  • const定义的变量不可修改,一般在require一个模块的时候用或者定义一些全局常量
  • 可以在全局作用域或者函数内声明常量,但是必须初始化常量
  • 常量不能和它所在作用域内其它变量或者函数拥有相同名称

4.let命令

  • 需要”javascript 严格模式”:‘use strict’; 不存在变量提升 不允许重复声明
  • let声明的变量作用域是在块级域中,函数内部使用let定义后,对函数外部无影响(块级作用域)
  • 可以在声明变量时为变量赋值,默认值为undefined,也可以稍后在脚本中给变量赋值,在生命前无法使用(暂时死区)

5.import命令
6. class命令

5.promise all race 的作用分别是什么
  1. Promise.all可以将多个Promise实例包装成一个新的Promise实例。同时,成功和失败的返回值是不同的,成功的时候返回的是一个结果数组,而失败的时候则返回最先被reject失败状态的值。
  2. Promse.race就是赛跑的意思,意思就是说,Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。
6.window.onload 和document.ready的区别
  • ready事件在DOM结构绘制完成之后就会执行,这样能确保就算有大量的媒体文件没加载出来,JS代码一样可以执行。
  • load事件必须等到网页中所有内容全部加载完毕之后才被执行。如果一个网页中有大量的图片的话,则就会出现这种情况:网页文档已经呈现出来,但由于网页数据还没有完全加载完毕,导致load事件不能够即时被触发。
7.如何准确的判断一个数据类型

先想一下前端的基本数据类型有哪些?

  • 基本数据类型:String、Boolean、Number、null、undefined
  • 复杂数据类型:Object

例如我们有以下一些数据

var bool = true
var num = 1
var str = 'abc'
var und = undefined
var nul = null
var arr = [1,2,3]
var obj = {name:'haoxl',age:18}
var fun = function(){console.log('I am a function')}

判断数据类型的方法有:

  1. typeof
console.log(typeof bool); //boolean
console.log(typeof num);//number
console.log(typeof str);//string
console.log(typeof und);//undefined
console.log(typeof nul);//object
console.log(typeof arr);//object
console.log(typeof obj);//object
console.log(typeof fun);//function

其中Array、Object、null打印的都是object

  1. 使用instanceof

instanceof不能区别undefined和null,而且对于基本类型如果不是用new声明的则也测试不出来,对于是使用new声明的类型,它还可以检测出多层继承关系。

  1. 使用constructor

constructor不能判断undefined和null,并且使用它是不安全的,因为contructor的指向是可以改变的

  1. 使用Object.prototype.toString.call

原理(摘自高级程序设计3):在任何值上调用 Object 原生的 toString() 方法,都会返回一个 [object NativeConstructorName] 格式的字符串。每个类在内部都有一个 [[Class]] 属性,这个属性中就指定了上述字符串中的构造函数名。 但是它不能检测非原生构造函数的构造函数名。

css
1.清除浮动

浮动可以理解为让某个元素脱离了正常文档流,与其他元素不在同一个层次上
如何清楚浮动呢?

  1. 可以设置属性clear : none | left | right | both
none默认值。允许两边都可以有浮动对象
left不允许左边有浮动对象
right不允许右边有浮动对象
both不允许有浮动对象

但是要记住一点:这个规则只能影响使用清除的元素本身,不能影响其他元素。

vue
1. vue双向数据绑定的原理

vue.js是通过数据劫持结合发布-订阅者模式,通过object.defineProperty()来劫持各个属性的gettersetter,在数据发生改变是通知订阅者,触发相应的监听回调

要实现mvvm的双向绑定,就必须要实现以下几点:

1、实现一个数据监听器Observer,能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者
2、实现一个指令解析器Compile,对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数
3、实现一个Watcher,作为连接Observer和Compile的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图
4、mvvm入口函数,整合以上三者

react
1.react中的受控组件和非受控组件

在React中,所谓受控组件和非受控组件,是针对表单而言的。

表单受控组件
  1. 表单元素依赖于状态,表单元素需要默认值实时映射到状态的时候,就是受控组件,这个和双向绑定相似.
  2. 受控组件,表单元素的修改会实时映射到状态值上,此时就可以对输入的内容进行校验.
  3. 受控组件只有继承React.Component才会有状态.
  4. 受控组件必须要在表单上使用onChange事件来绑定对应的事件.
非受控组件
  1. 非受控组件即不受状态的控制,获取数据就是相当于操作DOM。
  2. 非受控组件的好处是很容易和第三方组件结合。
小程序
1.小程序授权被拒绝后如何再次让用户授权

众所周知小程序的例如获取地址授权,在用户拒绝后就不会在弹出了,但是也可能存在误操作需要重新授权,这时候可以使用wx.openSetting()打开微信授权页面让用户手动授权

2.小程序登陆流程

点击查看

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

琞、小菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值