最近的几次面试、笔试都被考到了相关js语法,算法也不能少....
自建一个文件夹,保存js常考笔试面试题:
包含es6、this绑定、异步执行顺序分析
1.原型链
function Parent(name){
console.log(name);
this.name = name
}
function Child(name){
Parent.call(this,name)
}
Child.prototype = new Parent();
var child1 = new Child("child1")
console.log(1111)
console.log(child1)
console.log(Child.prototype)
2.冒泡、捕获的第三个参数:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件机制</title>
</head>
<body >
<div id="parent" style="height: 400px;width: 400px;background-color: cadetblue">
<div id="child" style="height: 200px;width: 200px; margin:0 auto; background-color: bisque" onclick="console.log('捕获之前 child self click')">
</div>
</div>
<script>
document.body.addEventListener("click",function () {
console.log('捕获 body click')
},true);
document.getElementById('parent').addEventListener("click",function () {
console.log('捕获 parent click')
},true);
document.getElementById('child').addEventListener("click",function () {
console.log('捕获 child click')
},true);
document.getElementById('parent').onclick =function(){
console.log('捕获之后 parent self click')
}
document.body.addEventListener("click",function () {
console.log('冒泡 body click')
},false);
document.getElementById('parent').addEventListener("click",function () {
console.log('冒泡 parent click')
},false);
document.getElementById('child').addEventListener("click",function () {
console.log('冒泡 child click')
},false);
document.body.onclick =function(){
console.log('冒泡之后 body self click')
}
</script>
</body>
</html>
3.数组操作
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
console.log("----------------------------111111")
let arr = [];
arr.push(1, 2, 3, 4, 5, "12345")
console.log(...arr)
console.log("----------------------------22222")
arr.splice(1, 3, "abc")
console.log(...arr)
</script>
</body>
</html>
4.数组方法:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// let arr = [];
// let len = 100;
// for (let i = 0; i < len; i++) {
// let x = Math.floor(Math.random()*len);
// console.log(x);
// arr.push(x)
// }
// console.log(arr)
// console.log("=================1111111111111111");
// var p1 = [];
// var p2 = [];
// var p3 = [];
// var p4 = [];
// var p5 = [];
// for(let i = 0;i<arr.length;i++){
// if(arr[i]<len*0.5 && arr[i]>0){
// debugger
// console.log(arr[i]);
// // console.log("-----1")
// p1.push(arr[i])
// }
// else {
// // console.log("-----2")
// p2.push(arr[i])
// }
// }
// console.log(p1.length)
// console.log(p2.length)
// for(let i =0 ;i<100;i++){
// let x = Math.ceil(Math.random()*100)
// // console.log(x)
// }
// console.log(first)
console.log("----------------------------111111")
let arr = [];
arr.push(1, 2, 3, 4, 5, "12345")
console.log(arr)
console.log("----------------------------22222")
arr.splice(1, 3, "abc")
console.log(arr)
console.log("----------------------------333333 删除")
let arr2 = [1, 2, 3, 54, 5, 6]
// let arr2n = arr2.pop()
// console.log(arr2n)
// let x = arr2.shift()
// console.log(x)
console.log("----------------------------333333 改")
console.log("splice")
console.log("-------------------------4444444444查")
let arr4 = [1, 34, 4, 5, 5, 6, 6, 6, 67, 7]
// console.log(arr4.indexOf(5))
console.log(arr4.includes(5))
console.log("-------------------------5555555555555》》》》》》》》》》》》》》》》 排序")
let paixu = [1, 32, 4, 5, 6, 6, 6, 67, 7, 7, 7, 7, 7, 9834634764587326, 37, 346, 4, 634, 673, 7, 37, 72, 62, 6, 6, 4, 472, 1, 74775873, 8, 348, 1]
console.log(...paixu.reverse())
console.log(...paixu.sort())
console.log("-------------------------666666666666》》》》》》》》》》》》》》》》》 转换")
let zh = ["jiba", '123', 'erg>gt', '14,', ' 32572 385 93 7892357ew ryg89 9^&*()(*&UIHG*&', ' 31 4 4a n', 'as ,', '234 234 , rwf f, , , , ', '13 43 ', 'asf . . .fa.s , ']
// console.log(first)
let zh1 = zh.join("<--->")
console.log(zh1)
console.log("-------------------------7777777777777777》》》》》》》》》》》》》》》》》 迭代操作:forEach filter map")
let feArr = [1, 2, 3, 4, 5, 4, 3, 2, 1];
feArr.forEach((item,index,array)=>{
// item=item+1
console.log("item是:",item," , index是:",index, " arr自己是: ",array)
})
console.log(feArr)
console.log("-----")
let filterArr = [1, 2, 3, 4, 5, 4, 3, 2, 1];
let newFtArr = filterArr.filter((item,index,array)=> {
return item%3 ==0
})
console.log(newFtArr)
console.log("-----")
let mapArr = [1, 2, 3, 4, 5, 4, 3, 2, 1];
let newMpArr = mapArr.map((item,value,array)=>{
return item*=10
});
console.log(newMpArr);
</script>
</body>
</html>
5.字符串方法:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
console.log("--------------------------1字符串方法--------------------------")
console.log("-------------------11111增加")
let stringValue = "hello string is here !!!"
let newString = stringValue.concat(" end of the newString");
console.log(newString)
console.log("-------------------2222222删除")
let shanString = "hello string is here !!!"
console.log(shanString.slice(6))
console.log(shanString.substring(0, 3))
console.log("-------------------333333 改")
let gaiString = " hello string is here !!! "
console.log(gaiString.length)
let gaiedString = gaiString.trim();
console.log(gaiedString.length)
console.log(gaiString.length)
console.log("-------------------44444444 查找")
let chaString = " hello string is here !!! "
console.log(chaString.charAt(3))
console.log(chaString.includes("hello"))
console.log("-------------------555555 转换")
let changeString = " hello . asfd. ey45ygf. .at45 .fs.dfas. s.f sd. .fs.f astr.a s.f.asf.s.3.4.5.eg.f45..t.ing is here !.!! ";
let aftArr = changeString.split(".")
console.log(...aftArr)
console.log("-------------------6666666 test function")
var i = 101;
for (; i--;) {
// console.log(i); // 从 1001 打印到 0
}
console.log("-------------------77777 100内质数function")
</script>
</body>
</html>
6. es6 常见语法:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
var p1 = Promise.resolve(1);
var p2 = Promise.resolve(p1);
var p3 = new Promise(function (resolve, reject) {
resolve(1);
});
var p4 = new Promise(function (resolve, reject) {
resolve(p1);
});
// 宏任务:
// 微任务:
console.log(p1, p2, p3, p4)
console.log(p1 === p2);
console.log(p1 === p3);
console.log(p1 === p4);
console.log(p3 === p4);
p4.then(function (value) {
console.log('p4=' + value);
});
p2.then(function (value) {
console.log('p2=' + value);
})
p1.then(function (value) {
console.log('p1=' + value);
})
</script>
</body>
</html>
7.异步加载对于浏览器
8.节流
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button>按钮</button>
<input type="text">
<!-- CDN引入: 网络的js文件 -->
<!-- <script src="https://cdn.jsdelivr.net/npm/underscore@1.13.4/underscore-umd-min.js"></script> -->
<!-- 本地引入: 下载js文件, 并且本地引入 -->
<script src="./js/underscore.js"></script>
<script>
// function hythrottle(fn, interval) {
// let startTime = 0
// const _throttle = function() {
// const nowTime = new Date().getTime()
// const waitTime = interval - (nowTime - startTime)
// if (waitTime <= 0) {
// fn()
// startTime = nowTime
// }
// }
// return _throttle
// }
//11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
function hythrottle(fn,interval){
let startTime = 0
let cnt
const _throttle = function(){
const nowTime = new Date().getTime()
const waitTime = nowTime - startTime
if(interval<=waitTime){
fn()
startTime = nowTime
}
}
return _throttle
}
</script>
<script>
// 1.获取input元素
const inputEl = document.querySelector("input")
// 2.underscore节流处理代码
// let counter = 1
// inputEl.oninput = _.throttle(function() {
// console.log(`发送网络请求${counter++}:`, this.value)
// }, 1000)
// 3.自己实现的节流函数
let counter = 1
inputEl.oninput = hythrottle(function() {
console.log(`发送网络请求${counter++}:`, this.value)
}, 1000)
</script>
</body>
</html>
为什么能狗执行限制时间间隔的函数?
返回的是一个函数!!!!
因为是一个闭包,startTime可以被从里面访问到,下次比较的是前一次的时间,
还有一种写法:
function throttle(fn, delay) {
let canUse = true;
return function() {
if (canUse) {
fn.apply(this, arguments);
canUse = false;
setTimeout(() => canUse = true, delay);
}
}
let F = true;
return function(){
if(F=true){
fn.apply(this,arguments);
F= false;
setTimeout(()=>f=true,delay);
}
}
}
9 快排
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
var arr = [3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48];
function quickSort(arr) {
if (arr.length <= 1) return arr;
var leftArr = [], rightArr = [], q = arr[0];
for (var i = 1; i < arr.length; i++) {
if (arr[i] > q) {
rightArr.push(arr[i]);
} else {
leftArr.push(arr[i]);
}
}
return [].concat(quickSort(leftArr), [q], quickSort(rightArr));
}
console.log(quickSort(arr))
console.log(1)
</script>
</body>
</html>
10 DOM:
虚拟node:node效率太低。190个属性。而现在只要3个步骤 》》》
- JavaScript 很快和直接操作 DOM 很慢,这是 Virtual DOM 得以实现的两个基本前提。
- 得益于 V8 引擎的出现,让 JavaScript 可以高效地运行,在性能上有了极大的提高。
- 直接操作 DOM 的低效和 JavaScript 的高效相对比,为 Virtual DOM 的产生提供了大前提。
- 三个步骤 》》》生成 Virtual DOM 树-比两棵树的差异-更新视图。
11.判断是否在页面可视区域:
// 防抖/节流
const scrollListenerHandler = throttle(() => {
if (el === window) {
clientHeight.value = document.documentElement.clientHeight
scrollTop.value = document.documentElement.scrollTop
scrollHeight.value = document.documentElement.scrollHeight
} else {
clientHeight.value = el.clientHeight
scrollTop.value = el.scrollTop
scrollHeight.value = el.scrollHeight
}
if (clientHeight.value + scrollTop.value >= scrollHeight.value) {
console.log("滚动到底部了")
isReachBottom.value = true
}
}, 100)
clinetHeight+scrollATop>scrollTop就能判断是否到了底部
11 insertAfter:
判断是否有下一个子元素节点----》》》1.如果有就在下一个兄弟元素前插入,2.没有就直接在当前附加一个子节点
HTMLElement.prototype.insertAfter = function(target, afterNode) {
var nextElem = afterNode.nextElementSibling;
if (nextElem) {
this.insertBefore(target, nextElem);
} else {
this.appendChild(target);
}
}
12 逆序排列元素的子节点:
...***function () {
var childElem = this.children,
childrenLen = childElem.length,
fragment = document.createDocumentFragment();
for (var i = childrenLen - 1; i >= 0; i--) {
fragment.appendChild(childElem[i]);
}
this.appendChild(fragement)
}
13.mouseOver 和mouseEnter有什么区别?
切换了都会处罚,只有进入才会:
所以要多一些,第一种
14.找一个最近的公共父亲节点?
***findFather(a,b){
for(;a;a=a.parentNode){
if(a.contains(b)){
return a;
}
}
}
15.手写深拷贝?
function deepCopyMyself(obj,cloneObj = new WeakMap()){
if(obj==null || typeof obj ==='Object' ||){
return obj ;
}
if(cloneObj.has(obj)){
return cloneObj.get(obj);
}
//处理对象
let newObj = {}
cloneObj.set(obj,newObj);
for(let i in obj ){
if(obj.hasOwnProperty(i)){
newObj[i] = deepCopyMyself(obj[i],cloneObj)
}
}
return newObj;
}
循环引用-----判断控制、原始类型》》》循环》》》遍历属性递归