用自己的话讲有趣的知识。大家好,我是梅巴哥er
。本篇介绍JS版块的知识总结。
前端知识总结系列:
JS版块
常用的学习网站:
- JS基础知识整理
- JQ基础知识整理
- JS进阶和ES基础知识整理
- MDN官网(快捷查询)
- B站搜黑马教程,pink老师讲的。
知识总结:
- click在ios上有300ms延迟,原因及如何解决?
- 苹果公司发布iPhone前遇到一个问题
- 当时都是为大屏幕设备设计的网站,没有适配小屏幕的软件
- 怎么办呢?
- 让用户双击,可以缩小屏幕,用户就可以在iPhone上用了
- 双击时间差是300ms,这就造成了click在ios上有300ms延迟的问题。
- 怎么解决呢?
- 在html文件的head标签里加js插件:
<script src="https://as.alipayobjects.com/g/component/fastclick/1.0.6/fastclick.js"></script>
- 参考博文:延迟解释和解决
- 参考博文:查看博文第12条
- addEventListener参数
- document.addEventListener()用来添加监听事件
element.addEventListener(event, function, useCapture)
- 第一个参数event,是告诉事件怎么发生,比如click
- 第二个参数function,是告诉事件发生了什么,比如
function() {alert('被点击了')}
- 第三个参数是布尔值,是告诉事件的触发顺序。
- false是冒泡阶段,true是捕获阶段。默认是false,可以不写。
- 比如,父盒子ul里有子盒子li,ul和li都添加点击事件
- 给ul设置为true,就是捕获阶段,触发顺序从ul到li,那么点击li,就会先触发ul的事件,再触发li的事件。
- 给ul设置false或不写,就是冒泡阶段,触发顺序从li到ul,那么点击li,就会先触发li的事件,再触发ul的事件。
- 根据W3C标准,先执行捕获阶段,再执行冒泡阶段。
- 如果是同一个节点同时绑定了捕获和冒泡事件,那就要看代码放置的顺序。哪个在前,就先执行哪个。
- 参考博文:参数及含义
- 说说前端中的事件流
- 如何让事件先冒泡后捕获
- 参考博文:先冒泡后捕获
- 说一下事件委托
- 事件委托,也叫事件代理,jq里叫事件委派。
- 事件委托,就是把子节点的事件委托给父节点。
- 好处是只操作父节点的DOM,提升性能。
- 比如父节点ul里有2个子节点li。
- 现在点击li让li变红,一般操作是给两个li都加监听事件。这就要操作两次DOM。
- 如果只给ul添加事件,当点击li的时候,通过冒泡原理,只需要操作一次ul事件即可。
- 通过
e.target
来判断点击的是哪个li就行了。 - jq里就更简单粗暴了。
$('ul').on('click', 'li', function() { alert(1); });
直接用$来绑定ul,在on事件里添加li就可以了。- 参考博文:事件委托
- 也可参考这个博文:进入页面Ctrl+f 事件委托
- mouseover和mouseenter的区别
- mouseenter不会冒泡
- mouseover会冒泡
- 参考博文、:区别
- js的new操作符做了哪些事情
- js的各种位置,比如clientHeight,scrollHeight,offsetHeight ,以及scrollTop, offsetTop,clientTop的区别?
clientHeigh
:返回自身包括padding、内容区的高度,不含边框,返回值不带单位scrollHeight
: 返回自身实际的高度,不含边框,返回值不带单位offsetHeight
: 返回自身包括padding、边框、内容区的高度,返回值不带单位scrollTop
: 返回被卷去的上侧距离,返回值不带单位offsetTop
: 返回元素相对带有定位父元素上方的偏移clientTop
: 返回元素上边框的大小- 参考博文:js位置详解
- js拖拽功能的实现(代码)
<!DOCTYPE HTML>
<html>
<head>
<title>offset案例:鼠标拖动盒子移动</title>
<meta charset="utf-8" />
<style>
* {
margin: 0;
padding: 0;
}
#box {
position: relative;
width: 200px;
height: 200px;
background-color: pink;
cursor: move;
}
</style>
</head>
<body>
<div id="box"> </div>
<script>
//鼠标按下触发 mousedown 鼠标移动 mousemove 鼠标松开 mouseup
var box = document.getElementById('box');
//鼠标按下 有一个坐标
/*var x2 = null;
var y2 = null;
var x1 = null;
var y1 = null;*/
box.addEventListener('mousedown', function(e) {
//先算出鼠标按下时,鼠标在盒子内的坐标
var x1 = e.pageX - box.offsetLeft;
var y1 = e.pageY - box.offsetTop;
//console.log(x1 +','+ y1);
//鼠标移动后的坐标减去鼠标在盒子内的坐标,就是盒子的坐标了
document.addEventListener('mousemove', move)
function move(e) {
var x2 = e.pageX - x1;
var y2 = e.pageY - y1;
//console.log(x2 +','+ y2);
box.style.left = x2 + 'px';
box.style.top = y2 + 'px';
}
//鼠标松开 移除移动事件,让盒子不再跟着鼠标走了
document.addEventListener('mouseup', function() {
document.removeEventListener('mousemove',move);
})
})
</script>
</body>
</html>
- 异步加载js的方法
- JS方法:
window.addEventListener('load', function() {...})
- JQ方法:
$(function(){...})
- async方法:
<script type="text/javascript" src="xxx.js" async></script>
- defer方法:
<script type="text/javascript" defer></script>
- es6方法:
<script type="module" src="xxx.js"></script>
- 参考博文:异步加载
- JS方法:
- js的节流和防抖
- 参考我的博文:节流和防抖
- JS中的垃圾回收机制
- 1,标记清除
- 2,引用计数
- 3,手动回收
- 参考博文1:垃圾回收的两种方法介绍
- 参考博文2:机制
- 对象深度克隆的简单实现
- 深克隆方法:var obj = Object.assign(target, …source)
- 深度克隆手写方法:核心思想是判断被克隆对象的
数据类型
,其次是遍历
,最后是递归
。
// 用递归方法
function clone(obj) {
var buf;
if(obj instanceof Array) {
buf = []; //创建一个空数组
var i = obj.length;
while(i--) {
buf[i] = clone(obj[i]);
}
return buf;
} else if(obj instanceof Object){
buf = {};
for(var k in obj){
buf[k] = clone(obj[k]);
}
return buf;
} else {
return obj;
}
}
//测试代码
var obj1 = {
a: 1,
b: {
x: [2, 3]
}
}
var b = clone(obj1);
console.log(b);
- 实现一个once函数,传入函数参数只执行一次
- 参考博文:once函数
- js监听对象属性的改变
- == 和 ===、以及Object.is的区别
- ==:判断值是否相等,不管数据类型
- ===:判断值和数据类型是否都一致
- Object.is(a, b):加强版的===,但是有点区别。
+0 === -0 //true ; Object.is(+0, -0) // false
NaN === NaN // false ; Object.is(NaN, NaN) // true
- 参考博文:区别
- setTimeout、setInterval和requestAnimationFrame之间的区别
- 参考博文:区别
- 用setTimeout来实现setInterval
// 可以限制次数的实现
function myInt(fn, ms) {
var i = 0
function inter() {
if(i == 3) {return;}
setTimeout(inter, ms)
fn()
i++
}
setTimeout(inter, ms)
}
function hi() {
console.log('hi')
}
myInt(hi, 1000)
-
- 参考博文:实现setInterval
-
js怎么控制一次加载一张图片,加载完后再加载下一张
-
Function.proto(getPrototypeOf)是什么?
-
js判断类型的方法有哪些
-
数组常用方法有哪些
- Array.length:数组元素个数。举例
[1,2,3].length // 3
- Array.isArray():判断是否为数组。举例
log = console.log; var arr = [1, 2, 3]; log(Array.isArray(arr)) // ture
- Array.of():转换成数组。举例
console.log(Array.of(1, 2)); // [ 1, 2 ]
- arr1.concat(arr2,arr3),得到一个新数组。举例
[1].concat([2], [3]) // [1, 2, 3]
- arr.fill(value, start, end),用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。不包括终止索引。举例
console.log([1,2,3].fill(4,1,2)) // [ 1, 4, 3 ]
- arr.filter() 遍历筛选满足条件的元素
- find() 查找满足条件的第一个元素
- findIndex()返回数组中满足提供的测试函数的第一个元素的索引
- forEach()方法对数组的每个元素执行一次提供的函数
- includes()用来判断一个数组是否包含一个指定的值,如果是,酌情返回 true或 false
- indexOf()返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回-1
- join()将数组(或一个类数组对象)的所有元素连接到一个字符串中
- map()创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果
- pop()从数组中删除最后一个元素,并返回该元素的值。此方法更改数组的长度
- push()将一个或多个元素添加到数组的末尾
- reduce()累加器和数组中的每个元素(从左到右)应用一个函数
- reverse方法将数组中元素的位置颠倒
- shift()从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度
- slice返回一个从开始到结束(不包括结束)选择的数组的一部分浅拷贝到一个新数组对象
- some()试数组中的某些元素是否通过由提供的函数实现的测试。结果是true或false
- unshift()将一个或多个元素添加到数组的开头,并返回新数组的长度
arr.sort(function(a, b) {return b-a}) 让数组从大到小排序
- 参考博文:数组方法
- Array.length:数组元素个数。举例
-
数组去重如何做
- 参考博文:去重
-
事件代理在捕获阶段的实际应用
- 可以在父元素层面阻止事件向子元素传播,也可代替子元素执行某些操作。
-
- e.target:返回真正的触发了事件的标签对象。这个会随着我们点击位置的不同,返回不同的标签对象,这个就和捕获、冒泡有关系
-
- e.currentTarget:返回绑定事件的标签对象。显然这个是不会变化的,只要事件绑定好了,自然返回的就总是同一个标签
- 参考博文:应用
-
去除字符串首尾空格的方法有哪些,说出尽可能多的方法
- str.trim()
- 参考博文:去除空格
-
能来讲讲JS的语言特性吗
- 封装:把属性和方法放一个函数里,用的时候就外部调用即可
- 继承:把多个能通用的方法和属性放一个构造函数或类里,然后调用
- 多态:对不同对象进行同一操作,会出现不同结果。
- 参考博文:封装 继承 多态
-
如何判断是否为数组
[1,2] instanceof Array // true
Object.prototype.toString.call([1, 2]) // true
console.log(Array.isArray([1, 2]))) // true
- 参考博文:判断数组
-
typeof怎么判断数组
- 参考博文:typeof数组
-
JS如何实现跨域,都有哪些方法
-
Js基本数据类型
- 数字型:number
- 字符串:string
- 布尔型:boolean
- null
- undefined
- 参考博文:基本数据类型
-
JS怎么实现全排列的算法,试写一段代码来实现。(全排列就是给定一个字符串,输出该字符串所有排列的可能。如输入“abc”,输出“abc,acb,bca,bac,cab,cba”。)
-
不同数据类型的值的比较,是怎么转换的,有什么规则
- 参考博文:转换
-
null == undefined,为什么?
- JS规范中,这俩值规定是相等的。
- 为啥呢?有不同的理解,参考博文:俩值相等为啥
-
什么是按需加载
- 顾名思义,就是按照项目的需求加载模块。没需求的模块就不加载。
- 比如用到antd时,不需要的模块就不需要加载了。或者用户看页面,往下拉滚动条,下面的内容再加载。用户不下拉滚动条,下面的内容就先不加载。
- 很显然的,优化了性能。提升了编程和用户体验。
- 参考博文:按需加载
-
说一下什么是virtual dom
- 通过JS对象模拟原生DOM。是对原生DOM 的抽象,极大的提升了DOM做的性能。
- 两大特点,抽象DOM,提升性能。
- 虚拟DOM怎么运行的呢?
- 首先模拟原生DOM,生成虚拟DOM树。
- 对比两棵树的差异
- 根据差异,更新视图
- 参考博文:virtual dom
- 参考博文:详细解释
-
写一个函数,第一秒打印1,第二秒打印2 。(用尽可能多的方法实现)
function print() {
function print1() {
console.log(1)
function print2() {
console.log(2)
}
setTimeout(print2, 1000)
}
setTimeout(print1, 1000)
}
print()
// 方法二
function print(n) {
for(let i = 1; i <= n; i++) {
setTimeout(() => console.log(i), 1000*i)
}
}
print(2)
// 注意:这里for循环里要用let,不能用var。
- 简单介绍一下symbol
- 参考博文:symbol
- 什么是事件监听
- 参考博文:事件监听
- 说说C++,Java,JavaScript这三种语言的区别
- 参考博文:语言区别
- js原型链,原型链的顶端是什么?Object的原型是什么?Object的原型的原型是什么?在数组原型链上实现删除数组重复数据的方法。
- 一两句话说不清楚,参看原型链
- 讲讲事件委托以及冒泡的原理
- 参考博文:原理和解释
- 写个函数,可以转化下划线命名到驼峰命名
- 深浅拷贝的区别和实现
- 参考博文:浅拷贝、深拷贝的分析
- JS中string的startwith和indexof两种方法的区别
- 参考博文:区别
- js字符串转数字的方法
- 有了解过事件模型吗,DOM0级和DOM2级有什么区别,DOM的分级是什么
- 平时是怎么调试JS的
- JS的基本数据类型有哪些,基本数据类型和引用数据类型的区别,NaN是什么的缩写,JS的作用域类型,undefined==null返回的结果是什么,undefined与null的区别在哪,写一个函数判断变量类型
- 以上4个问题,参考阅读:处理
- setTimeout(fn,100);100毫秒是如何权衡的
- 怎么获得对象上的属性:比如说通过Object.key()
- 了解事件代理吗,这样做有什么好处
- 给出以下代码,输出的结果是什么?原因? for(var i=0;i<5;i++) { setTimeout(function(){ console.log(i); },1000); } console.log(i)
- 以上几个问题,参考阅读权衡----输出结果
- js加载过程阻塞,解决方法
- js对象类型,基本对象类型以及引用对象类型的区别
- JavaScript中的轮播实现原理?假如一个页面上有两个轮播,你会怎么实现?
- 写一段代码,来计算输入的一个年份中有多少周
- 引用类型常见的对象
- assign的深拷贝
- arguments
- Eventloop
- 以上问题,参考阅读:参考
- jquery源代码考查
- 给定jquery的一个方法,讲讲它的实现原理
- 以上俩问题,参考阅读:jquery
- 关于dom的api有什么
- 参考阅读:dom的api
- 知道touch事件吗
- 参考博文:touch事件
- 数组移除第一个元素的方法有哪些?
- 参考博文:移除
- 把多维数组变成一维数组的方法
- 参考博文:拉平数组
- 数组的去重,尽可能写出多个方法
- 参考博文:12种方法
- 如果有一个大的数组,都是整型,怎么找出最大的前10个数
- 参考算法:找数字算法
- 知道数据结构里面的哪些常见的数据结构
- 参考博文:数据结构
- 找出数组中第k大的数组出现多少次,比如数组【1,2,4,4,3,5】第二大的数字是4,出现两次,所以返回2 。(考查实际代码操作,这块是考查比重最大的)
- 参考博文:找数字
- 合并两个有序数组
- 给一个数,去一个已经排好序的数组中寻找这个数的位置(通过快速查找,二分查找)
- 有一个矩形,用一个矩形(这个矩形和上个矩形没有任何关系)去裁剪原来那个矩形,剩下的部分,怎么用一个线分成两个面积相等的部分