本篇文章主要写的是前端高频面试题JavaScript篇(下),如果有需要
http/html/浏览器
方面面试题的小伙伴们,请在下方评论区留言,有时间我会去更新一篇相关面试题。如果没有的话,下一篇预备更新 前端高频面试题vue篇面试题参考文章:
- 【Web前端面试】葵花宝典(2022版本)—— CSS篇
- 【Web前端面试】葵花宝典 (2022版本)—— JS篇(上)
- 【Web前端面试】葵花宝典(2022版本)—— JS篇(下)
- 【Web前端面试】葵花宝典(2022版本)—— Vue篇
- 【JavaScript】中this指向相关的经典面试题
- 【JavaScript】作用域提升面试题(详解)
// 方法一:从原型入手
Array.prototype.isPrototypeOf(obj)
// 方法二:从构造函数入手
obj instanceof Array
// 方法三:跨原型链调用toString()
Object.prototype.toString.call(obj)
// 方法四:Array.isArray()
Array.isArray()
基本数据类型:undefined
、null
、number
、boolean
、string
、symbol
var deepCopy = function (obj) {
if (typeof obj !== 'object') return;
var newObj = obj instanceof Array ? [] : {};
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key];
}
}
return newObj;
}
跨域,是指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对 JavaScript 实施的安全限制,那么只要协议、域名、端口有任何一个不同,都被当 作是不同的域。
跨域原理,即是通过各种方式,避开浏览器的安全限制。
要比较相等性之前,不能将 null 和 undefined 转换成其他任何值,但 null == undefined 会返回 true 。ECMAScript 规范中是这样定义的。
详解请参考如下链接:
JavaScript中this四种绑定规则优先级比较与箭头函数中的this获取
在代码块内,使用 let、const 命令声明变量之前,该变量都是不可用的。这在语法上, 称为“暂时性死区”
当用户触发了动作时才加载对应的功能。触发的动作,是要看具体的业务场景而言,包括但不限于以下几个情况:鼠标点击、输入文字、拉动滚动条,鼠标移动、窗口大小更 改等。加载的文件,可以是 JS、图片、CSS、HTML 等。
webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包 含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
优点:组件非常全面,样式效果也都比较不错。
缺点:框架自定义程度低,默认UI风格修改困难。
1、原型链继承,将父类的实例作为子类的原型,他的特点是实例是子类的实例也是父 类的实例,父类新增的原型方法/属性,子类都能够访问,并且原型链继承简单易于实 现,缺点是来自原型对象的所有属性被所有实例共享,无法实现多继承,无法向父类构 造函数传参。
2、构造继承,使用父类的构造函数来增强子类实例,即复制父类的实例属性给子类, 构造继承可以向父类传递参数,可以实现多继承,通过 call 多个父类对象。但是构造继 承只能继承父类的实例属性和方法,不能继承原型属性和方法,无法实现函数服用,每 个子类都有父类实例函数的副本,影响性能
3、实例继承,为父类实例添加新特性,作为子类实例返回,实例继承的特点是不限制 调用方法,不管是 new 子类()还是子类()返回的对象具有相同的效果,缺点是实 例是父类的实例,不是子类的实例,不支持多继承
4、拷贝继承:特点:支持多继承,缺点:效率较低,内存占用高(因为要拷贝父类的 属性)无法获取父类不可枚举的方法(不可枚举方法,不能使用 for in 访问到)
5、组合继承:通过调用父类构造,继承父类的属性并保留传参的优点,然后通过将父 类实例作为子类原型,实现函数复用
6、寄生组合继承:通过寄生方式,砍掉父类的实例属性,这样,在调用两次父类的构 造的时候,就不会初始化两次实例方法/属性,避免的组合继承的缺点
for (let i = 0; i < 5; i++) {
setTimeout(function () {
console.log(i)
}, 1000 * i)
}
Symbol 是 ES6 的新增属性,代表用给定名称作为唯一标识,这种类型的值可以这样创 建,
let id=symbol(“id”)
Symbol 确保唯一,即使采用相同的名称,也会产生不同的值,我们创建一个字段,仅为 知道对应 symbol 的人能访问,使用 symbol 很有用,symbol 并不是 100%隐藏,有内置方 法
Object.getOwnPropertySymbols(obj)
可以获得所有的 symbol。也有一个方法
Reflect.ownKeys(obj)
返回对象所有的键,包括 symbol。 所以并不是真正隐藏。但大多数库内置方法和语法结构遵循通用约定他们是隐藏的。
addEventListener
addEventListener()
方法,用于向指定元素添加事件句柄,它可以更简单的控制事件语法:
element.addEventListener(event, function, useCapture)
第一个参数是事件的类型(如 “
click
” 或 “mousedown
”).第二个参数是事件触发后调用的函数。
第三个参数是个布尔值用于描述事件是冒泡还是捕获。该参数是可选的。
事件传递有两种方式,冒泡和捕获 。
事件传递定义了元素事件触发的顺序,如果你将 P 元素插入到 div 元素中,用户点击 P 元素, 在冒泡中,内部元素先被触发,然后再触发外部元素, 捕获中,外部元素先被触发,在触发内部元素。
Promise 是一个对象,保存着未来将要结束的事件,它有两个特征:
- 对象的状态不受外部影响,Promise 对象代表一个异步操作,有三种状态,pending 进行中,fulfilled 已成功,rejected 已失败,只有异步操作的结果,才可以决定当前是哪 一种状态,任何其他操作都无法改变这个状态,这也就是 promise 名字的由来
- 一旦状态改变,就不会再变,promise 对象状态改变只有两种可能,从 pending 改到fulfilled 或者从 pending 改到 rejected,只要这两种情况发生,状态就凝固了,不会再改 变,这个时候就称为定型 resolved
Promise的基本用法:
let promise1 = new Promise(function (resolve, reject) { setTimeout(function () { resolve('ok') }, 1000) }) promise1.then(function success (val) { console.log(val) })
事件冒泡,就是元素自身的事件被触发后,如果父元素有相同的事件,如
onclick
事件, 那么元素本身的触发状态就会传递,也就是冒到父元素,父元素的相同事件也会一级一 级根据嵌套关系向外触发,直到document/window
,冒泡过程结束。
startsWith
和 indexof
两种方法的
startsWith()
方法用来判断当前字符串是否以另外一个给定的子字符串开头,并根据判断结果返回true
或false
。
Indexof
函数,indexof
函数可返回某个指定字符串在字符串中首次出现的位置。
通过函数
parseInt()
,可解析一个字符串,并返回一个整数,语法为parseInt(string ,radix)
- string:被解析的字符串
- radix:表示要解析的数字的基数,默认是十进制,如果 radix<2 或>36,则返回
NaN
- var 声明的变量是全局或者整个函数块的
- let、const声明的变量是块级的变量
- var声明的变量存在变量提升,let、const不存在
- let声明的变量允许重新赋值,const不允许
箭头函数与普通函数的区别在于:
- 箭头函数没有 this,所以需要通过查找作用域链来确定 this 的值,这就意味着如果箭 头函数被非箭头函数包含,this 绑定的就是最近一层非箭头函数的 this
- 箭头函数没有自己的 arguments对象,但是可以访问外围函数的 arguments 对象
- 不能通过 new 关键字调用,同样也没有
new.target
值和原型
- 一般是用浏览器自带的控制台
- node终端
setTimeout(fn,100);
100毫秒是如何权衡的
setTimeout()
函数只是将事件插入了任务列表,必须等到当前代码执行完,主线程才会去执行它指定的回调函数,有可能要等很久,所以没有办法保证回调函数一定会在setTimeout
指定的时间内执行,100 毫秒是插入队列的时间+等待的时间。
Object.key()
从 ES5 开始,有三种方法可以列出对象的属性
for(let i in obj
):该方法依次访问一个对象及其原型链中所有可枚举的类型
object.keys
:返回一个数组,包括所有可枚举的属性名称
object.getOwnPropertyNames
:返回一个数组包含不可枚举的属性
call 和 apply 的作用是一模一样的,只是传参的形式有区别而已
- 改变 this 的指向
- 借用别的对象的方法
- 调用函数,因为 apply,call 方法会使函数立即执
事件代理/事件委托:利用了事件冒泡,只指定一个事件处理程序,就可以管理某一类 型的事件。
简而言之:事件代理就是说我们将事件添加到本来要添加的事件的父节点,将事件委托给父节点来触发处理函数,这通常会使用在大量的同级元素需要添加同一类事件的时候, 比如一个动态的非常多的列表,需要为每个列表项都添加点击事件,这时就可以使用事 件代理,通过判断
e.target.nodeName
来判断发生的具体元素,这样做的好处是减少事件 绑定,同事动态的 DOM 结构任然可以监听,事件代理发生在冒泡阶段
public 表明该数据成员、成员函数是对所有用户开放的,所有用户都可以直接进行调用
private 表示私有,私有的意思就是除了 class 自己之外,任何人都不可以直接使用
async
和 await
具体该怎么用?(async () = > {
await new promise();
})()
promise
,await/async
,let
、const
、块级作用域、箭头函数
promise
和 await/async
的关都是异步编程的解决方案
指定 script 标签的 async 属性。
如果
async="async"
,脚本相对于页面的其余部分异步地执行(当页面继续进行解析时, 脚本将被执行)如果不使用 async 且
defer="defer"
:脚本将在页面完成解析时执行
图片轮播的原理就是图片排成一行,然后准备一个只有一张图片大小的容器,对这个容 器设置超出部分隐藏,在控制定时器来让这些图片整体左移或右移,这样呈现出来的效 果就是图片在轮播了。
如果有两个轮播,可封装一个轮播组件,供两处调用。
Object、Array、RegExp、Date、Function、特殊的基本包装类型(String、Number、Boolean) 以及单体内置对象(Global、Math)等
ES6 提供了更接近传统语法的写法,引入了 Class (类)这个概念,作为对象的模板。通过class关键字,可以定义类。
- 创建一个类的实例:创建一个空对象
obj
,然后把这个空对象的__proto__
设置为构造 函数的prototype
- 初始化实例:构造函数被传入参数并调用,关键字 this 被设定指向该实例
obj
。- 返回示例
obj
。
没有
promise
可以使用回调函数代替。
把一个元素响应事件(
click
、keydown
……)的函数委托到另一个元素;优点:减少内存消耗、动态绑定事件。
arguments
arguments是类数组对象,有length属性,不能调用数组方法
可以用
Array.from()
转换更详细内容请看:JavaScript中的Arguments对象
JavaScript相关面试题就更新到这里啦,相关 Web前端面试题 可以订阅专栏哦
专栏地址:《面试必看》
⏳ 名 言 警 句 : 说 能 做 的 做 说 过 的 \textcolor{red} {名言警句:说能做的做说过的} 名言警句:说能做的做说过的
✨ 原 创 不 易 , 还 希 望 各 位 大 佬 支 持 一 下 \textcolor{blue}{原创不易,还希望各位大佬支持一下} 原创不易,还希望各位大佬支持一下
点 赞 , 你 的 认 可 是 我 创 作 的 动 力 ! \textcolor{green}{点赞,你的认可是我创作的动力!} 点赞,你的认可是我创作的动力!
⭐️ 收 藏 , 你 的 青 睐 是 我 努 力 的 方 向 ! \textcolor{green}{收藏,你的青睐是我努力的方向!} 收藏,你的青睐是我努力的方向!
✏️ 评 论 , 你 的 意 见 是 我 进 步 的 财 富 ! \textcolor{green}{评论,你的意见是我进步的财富!} 评论,你的意见是我进步的财富!