本篇文章主要写的是前端高频面试题JavaScript篇(上),如果有需要http/html/浏览器
方面面试题的小伙伴们,请在下方评论区留言,下下一篇我会更新相关面试题。如果没有的话,下一篇预备更新 前端高频面试题JavaScript篇(下)
- 【Web前端面试】葵花宝典(2022版本)—— CSS篇
- 【Web前端面试】葵花宝典 (2022版本)—— Vue 篇
- 【Web前端面试】葵花宝典(2022版本)—— JS篇(下)
- 【JavaScript】中this指向相关的经典面试题
- 【JavaScript】作用域提升面试题(详解)
误区:我们经常说 get 请求参数的大小存在限制,而 post 请求的参数大小是无限制的。 实际上 HTTP 协议从未规定 GET/POST 的请求长度限制是多少。对 get 请求参数的限制 是来源与浏览器或 web 服务器,浏览器或 web 服务器限制了 url 的长度。
为了明确这个概念,我们必须再次强调下面几点:
闭包就是能够读取其他函数内部变量的函数,或者子函数在外调用, 子函数所在的父函数的作用域不会被释放。
promise
、generator
、async/await
事件流描述的是从页面中接收事件的顺序,DOM2 级事件流包括下面几 阶段。
事件捕获阶段
处于目标阶段
事件冒泡阶
HTML 中与 javascript 交互是通过事件驱动来实现的,例如鼠标点击事件 onclick、页面 的滚动事件 onscroll 等等,可以向文档或者文档中的元素添加事件侦听器来预订事件。 想要知道这些事件是在什么时候进行调用的,
在 DOM 标准事件模型中,是先捕获后冒泡。但是如果要实现先冒泡后捕获的效果,对于同一个事件,监听捕获和冒泡,分别对应相应的处理函数,监听到捕获事件,先暂缓 执行,直到冒泡事件被捕获后再执行捕获之间。
事件委托指的是,不在事件的发生地(直接 dom
)上设置监听函数,而是在其父 元素上设置监听函数,通过事件冒泡,父元素可以监听到子元素上事件的触发,通过判 断事件发生元素 DOM 的类型,来做出不同的响应
举例:最经典的就是 ul
和 li
标签的事件监听,比如我们在添加事件时候,采用事件委 托机制,不会在 li 标签上直接添加,而是在 ul 父元素上添加。 好处:比较合适动态元素的绑定,新添加的子元素也会有监听函数,也可以有事件触发 机制。
预加载:提前加载图片,当用户需要查看时可直接从本地缓存中渲染。
懒加载:懒加载的主要目的是作为服务器前端的优化,减少请求数或延迟请求数。
两种技术的本质:两者的行为是相反的,一个是提前加载,一个是迟缓甚至不加载。 懒加载对服务器前端有一定的缓解压力作用,预加载则会增加服务器前端压力。
mouseover
和 mouseenter
的区别mouseover
:当鼠标移入元素或其子元素都会触发事件,所以有一个重复触发,冒泡的过程。对应的移除事件是 mouseout
mouseenter
:当鼠标移除元素本身(不包含元素的子元素)会触发事件,也就是不会冒泡,对应的移除事件是 mouseleave
new 操作符新建了一个空对象,这个对象原型指向构造函数的 prototype,执行构造函数后返回这个对象。
通过 apply
和 call
改变函数的 this 指向,他们两个函数的第一个参数都是一样的表示要 改变指向的那个对象,第二个参数,apply 是数组,而 call 则是 arg1,arg2…这种形式。
通 过 bind
改变 this
作用域会返回一个新的函数,这个函数不会马上执行。
详解可以参考这篇文章http://t.csdn.cn/GNtKH
clientHeight
,scrollHeight
,offsetHeight
,以及 scrollTop
, offsetTop
,clientTop
的区别?clientHeight
:表示的是可视区域的高度,不包含 border 和滚动条offsetHeight
:表示可视区域的高度,包含了 border 和滚动条scrollHeight
:表示了所有区域的高度,包含了因为滚动被隐藏的部分。clientTop
:表示边框 border 的厚度,在未指定的情况下一般为 0scrollTop
:滚动后被隐藏的高度,获取对象相对于由 offsetParent
属性指定的父坐标(css 定位的元素或 body 元素)距离顶端的高度首先是三个事件,分别是 mousedown,mousemove,mouseup 当鼠标点击按下的时候,需要一个 tag 标识此时已经按下,可以执行 mousemove 里面的 具体方法。
clientX,clientY 标识的是鼠标的坐标,分别标识横坐标和纵坐标,并且我们用 offsetX 和 offsetY 来表示元素的元素的初始坐标,移动的举例应该是:
鼠标移动时候的坐标-鼠标按下去时候的坐标。
也就是说定位信息为: 鼠标移动时候的坐标-鼠标按下去时候的坐标+元素初始情况下的 offetLeft。
还有一点也是原理性的东西,也就是拖拽的同时是绝对定位,我们改变的是绝对定位条 件下的 left 以及 top 等等值。
补充:也可以通过 html5 的拖放(Drag 和 drop)来实现
defer:只支持 IE 如果您的脚本不会改变文档的内容,可将 defer 属性加入到标 签中,以便加快处理文档的速度。
因为浏览器知道它将能够安全地读取文档的剩余部分而不用执行脚本,它将推迟对脚本的解释,直到文档已经显示给用户为止。
async,HTML5 属性仅适用于外部脚本,并且如果在 IE 中,同时存在 defer 和 async,那 么 defer 的优先级比较高,脚本将在页面完成时执行。创建 script 标签,插入到 DOM 中
anyAjaxObj.setRequestHeader("If-Modified-Since","0")
。anyAjaxObj.setRequestHeader("Cache-Control","no-cache")
。"fresh=" + Math.random()
。"nowtime=" + new Date().getTime()
。$.ajaxSetup({cache:false})
。这样页面的所有 ajax 都会执行这条语句就是不需要保存缓存记录。js的垃圾回收机制就是定时回收闲置资源的一种机制 , 每隔一段时间, 执行环境都会清理内存中一些没用的变量释放它所占用的内存 。
核心思想 : 找到没用的变量, 释放它们的内存
它的功能是将对应的字符串解析成 JS 并执行,应该避免使用 JS,因为非常消耗性能(2 次,一次解析成 JS,一次执行)
**详细案例可以参考这篇文章:**http://t.csdn.cn/rvbx9
前端模块化就是复杂的文件编程一个一个独立的模块,比如 JS 文件等等,分成独立的 模块有利于重用(复用性)和维护(版本迭代),这样会引来模块之间相互依赖的问题, 所以有了 commonJS
规范,AMD,CMD 规范等等,以及用于 JS 打包(编译等处理)的 工具 webpack
CommonJS:开始于服务器端的模块化,同步定义的模块化,每个模块都是一个单独的 作用域,模块输出,modules.exports,模块加载 require()引入模块。
AMD:中文名异步模块定义的意思。
requireJS 实现了 AMD 规范,主要用于解决下述两个问题。 1.多个文件有依赖关系,被依赖的文件需要早于依赖它的文件加载到浏览器 2.加载的时候浏览器会停止页面渲染,加载文件越多,页面失去响应的时间越长。 语法:requireJS 定义了一个函数 define,它是全局变量,用来定义模块。
> 总结 AMD 规范:require()函数在加载依赖函数的时候是异步加载的,这样浏览器不 会失去响应,它指定的回调函数,只有前面的模块加载成功,才会去执行。 因为网页在加载 JS 的时候会停止渲染,因此我们可以通过异步的方式去加载 JS,而如果 需要依赖某些,也是异步去依赖,依赖后再执行某些方法。
function deepClone (obj) {
var newObj = obj instanceof Array ? [] : {};
for (var item in obj) {
var temple = typeof obj[item] == 'object' ? deepClone(obj[item]) : obj[item];
newObj[item] = temple;
}
return newObj;
}
ES5 的常用的对象克隆的一种方式。注意数组是对象,但是跟对象又有一定区别,所以 我们一开始判断了一些类型,决定 newObj 是对象还是数组。
function ones (func) {
var tag = true;
return function () {
if (tag == true) {
func.apply(null, arguments);
tag = false;
}
return undefined
}
}
场景假设:我们假设这里有一个 user 对象
Object.defineProperty(user, 'name', {
set:function (key, value) {
}
})
缺点:如果
id
不在user
对象中,则不能监听id的变化
var user = new Proxy({},{
set:function (target, key, value, receiver) {
}
})
这样即使有属性在
user
中不存在,通过user.id
来定义也同样可以这样监听这个属性的 变化哦
obj = {
name: yuxiaoliang, getName: function () {
return this.name
}
}
object.defineProperty(obj, "name", {
//不可枚举不可配置
});
通过defineProperty新增的属性,该新属性是不可修改、不可删除以及不可枚举的
function product () {
var name = 'why';
this.getName = function () {
return name;
}
}
var obj = new product();
Function.__proto__(getPrototypeOf)
是什么获取一个对象的原型,在 chrome 中可以通过_proto_的形式,或者在 ES6 中可以通过 Object.getPrototypeOf 的形式。 那么 Function.proto 是什么么?也就是说 Function 由什么对象继承而来,我们来做如下判别。
Function.__proto__==Object.prototype //false
Function.__proto__==Function.prototype//true
我们发现 Function 的原型也是Function
JavaScript中this指向相关的经典面试题
typeof()
instanceof
Object.prototype.toString.call()
等push()
,pop()
,shift()
,unshift()
,splice()
,sort()``,reverse()
,map()
示例代码可以查看该链接文章: 【JavaScript】高级语法——常用的数组处理方法
Array.from(new Set(array))
Object[value1] = true
, 在判断另一个值的时候,如果 Object[value2]
存在的话,就说明该值是重复的。有关闭包的详细讲解参考下文:
(详解)JavaScript中的闭包是什么?JavaScript中闭包造成的内存泄漏又怎么解决?
可以在父元素层面阻止事件向子元素传播,也可代替子元素执行某些操作。
使用正则(^\s*)|(\s*$)即可
lazyLoad
✨ 原 创 不 易 , 还 希 望 各 位 大 佬 支 持 一 下 \textcolor{blue}{原创不易,还希望各位大佬支持一下} 原创不易,还希望各位大佬支持一下
点 赞 , 你 的 认 可 是 我 创 作 的 动 力 ! \textcolor{green}{点赞,你的认可是我创作的动力!} 点赞,你的认可是我创作的动力!
⭐️ 收 藏 , 你 的 青 睐 是 我 努 力 的 方 向 ! \textcolor{green}{收藏,你的青睐是我努力的方向!} 收藏,你的青睐是我努力的方向!
✏️ 评 论 , 你 的 意 见 是 我 进 步 的 财 富 ! \textcolor{green}{评论,你的意见是我进步的财富!} 评论,你的意见是我进步的财富!