题源来自牛客网 在线编程---JS篇---前端面试手撕题
1.事件委托(获取标签然后创建点击事件的过程)
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
</head>
<body>
<ul>
<li>.</li>
<li>.</li>
<li>.</li>
</ul>
<script type="text/javascript">
// 补全代码
var point = document.querySelector('ul')
point.onclick = function(e){
e.target.innerText +='.'
}
</script>
</body>
</html>
2.数组去重(方法有很多,这里用最简单的方法,es6中的Set()来去重 )
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
</head>
<body>
<script type="text/javascript">
const _deleteRepeat = array => {
// 补全代码
return Array.from(new Set(array))
}
</script>
</body>
</html>
3.合法的URL(两种方法选其一即可,一种使用正则表达式,一种是用includes)
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
</head>
<body>
<script type="text/javascript">
const _isUrl = url => {
// 使用正则 test() 方法是正则表达式的一个方法,用于检测一个字符串是否匹配某个模式.
//test 方法检查字符串是否与给出的正则表达式模式相匹配,如果是则返回 true,否则就返回 false。
// return /^https/.test(url)
//使用includes
//includes方法返回一个布尔值,表示某个数组是否包含给定的值,与字符串的includes方法类似。
return url.includes("https")
}
</script>
</body>
</html>
4.快速排序
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
</head>
<body>
<script type="text/javascript">
const _quickSort = array => {
// 补全代码
if(array.length<=1) return array
// 寻找中位数
let middleIndex = Math.floor(array.length/2)
let middle = array.splice(middleIndex,1)[0]
let left = []
let right = []
for(let i=0;i<array.length;i++){
array[i]<middle?left.push(array[i]):right.push(array[i])
}
return [... _quickSort(left),middle,... _quickSort(right)]
}
</script>
</body>
</html>
5.全排序
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
</head>
<body>
<script type="text/javascript">
const _permute = string =>{
if(string.length === 1){
return [string]
};
let arr = string.split('');
// 存放每次生成的字符串
let result = []
for(let i=0;i<string.length;i++){
// 通过过滤,拿到除去前一个字母剩下的
restArr = arr.filter(item => item!=arr[i])
// 组合成数组
let newArr = _permute(restArr.join(''))
// 得到的结果合并成一个数组
result = result.concat(newArr.map(item=>arr[i]+item));
}
return result
}
</script>
</body>
</html>
6.instanceof
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
</head>
<body>
<script type="text/javascript">
const _instanceof = (target, Fn) => {
// 补全代码
return target instanceof Fn
}
</script>
</body>
</html>
7.Array.map
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
</head>
<body>
<script type="text/javascript">
// 补全代码
Array.prototype._map = function(fn){
//首先判断是否为函数
if(typeof fn !== 'function') return
//创建一个空数组来承载内容
const array = this
const newArray = new Array(array.length)
//遍历,将返回值添加进空数组
for(let i=0;i<array.length;i++){
newArray[i] = fn.call(arguments[1],array[i],i,array)
}
return newArray
}
</script>
</body>
</html>
8.Array.filter
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
</head>
<body>
<script type="text/javascript">
// 补全代码
Array.prototype._filter = function(fn){
const res = []
for(const i of this){
if(fn(i)){
res.push(i)
}
}
return res
}
</script>
</body>
</html>
9.Array.reduce
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
</head>
<body>
<script type="text/javascript">
// 补全代码
Array.prototype._reduce = function(f,pre=0){
this.forEach(item=>{
pre = f(pre,item)
})
return pre
}
</script>
</body>
</html>
10.objectCreate
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
</head>
<body>
<script type="text/javascript">
const _objectCreate = proto => {
// 补全代码
let obj = {}
return obj._proto_ = proto
}
</script>
</body>
</html>
11.Function.call
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
</head>
<body>
<script type="text/javascript">
// 补全代码
Function.prototype._call = function(obj,...args){
obj.fn = this
return obj['fn'](...args)
}
</script>
</body>
</html>
12.Function.bind
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
</head>
<body>
<script type="text/javascript">
// 补全代码
Function.prototype._bind = function(obj){
let that = this
return function(...arr){
return that.apply(obj,arr)
}
}
</script>
</body>
</html>
13.new
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
</head>
<body>
<script type="text/javascript">
const _new = function(fn, ...args) {
// 补全代码
// 1、创建一个新的对象
const obj = {}
// 2、将新对象的原型设置为构造函数的原型对象
obj.__proto__ = fn.prototype
// 3、将this绑定到新的对象上
const res = fn.apply(obj, args)
// 4、返回一个对象
return res instanceof Object ? res : obj
}
</script>
</body>
</html>
14.Object.freeze (冻结,简单的就是理解为不可以在进行增删改查)
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
</head>
<body>
<script type="text/javascript">
const _objectFreeze = object => {
// 首先判断传入是否为对象
if(object instanceof Object){
//seal()方法可以让对象不被扩张、删除等
Object.seal(object);
//遍历对象中的属性
for(let p in object){
//修改属性对象中的可写属性为false
Object.defineProperty(object,p,{
writable:false,
});
//实现深冻结
_objectFreeze(object[p]);
}
}else{
Object.seal(object)
}
}
</script>
</body>
</html>
15.浅拷贝
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
</head>
<body>
<script type="text/javascript">
const _shallowClone = target => {
// 补全代码
var obj = Object.assign({},target)
return obj
}
</script>
</body>
</html>
16.简易深拷贝
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
</head>
<body>
<script type="text/javascript">
const _sampleDeepClone = target => {
// 两种方式
//1.转换形式
//return JSON.parse(JSON.stringify(target))
//2.递归
var Obj = target instanceof Array ? [] : {}
for(let i in target){
if(typeof target[i] === 'object'){
Obj[i] = _sampleDeepClone(target[i])
}else{
Obj[i] = target[i]
}
}
return Obj
}
</script>
</body>
</html>
17.深拷贝
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
</head>
<body>
<script type="text/javascript">
const _completeDeepClone = (target, map = new Map()) => {
// 首先判断是否为空,为空则直接返回
if(target === null || typeof target!=='object') return target
//获取对象的构造函数名,判断是否为题目中四种情况之一
const constructor = target.constructor
if(/^(Function|RegExp|Date|Map|Set)$/i.test(constructor.name)){
return new constructor(target)
}
// 在Map对象中获取当前参数对象,如果能获取到,则说明这里为循环引用并返回Map对象中该参数对象的值
if(map.get(target)) return map.get(target)
map.set(target,true)
//根据该参数的数据类型是否为数组创建新对象
const cloneT = Array.isArray(target)?[]:{}
//遍历该对象参数,将每一项递归调用该函数本身的返回值赋给新对象
for(prop in target){
if(target.hasOwnProperty(prop)){
cloneT[prop] = _completeDeepClone(target[prop],map)
}
}
return cloneT
}
</script>
</body>
</html>
18.寄生组合式继承
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
</head>
<body>
<script type="text/javascript">
// 补全代码
function Human(name) {
this.name = name
this.kingdom = 'animal'
this.color = ['yellow', 'white', 'brown', 'black']
}
Human.prototype.getName = function(){
return this.name
}
function Chinese(name,age) {
Human.call(this,name)
this.color = 'yellow'
this.age = age
}
Chinese.prototype = Object.create(Human.prototype)
Chinese.prototype.constructor = Chinese
Chinese.prototype.getAge = function(){
return this.age
}
</script>
</body>
</html>
19.发布订阅模式
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
</head>
<body>
<script type="text/javascript">
class EventEmitter {
//首先需要把所有的订阅者存储起来
constructor(){
this.events = {}
}
//通过on来实现添加订阅事件
on(event,fn){
if(this.events[event]){
this.events[event].push(fn)
}else{
this.events[event] = [fn]
}
}
//通过emit来触发事件
emit(event){
this.events[event].map(callback=>callback())
}
}
</script>
</body>
</html>
20.观察者模式
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
</head>
<body>
<script type="text/javascript">
// 被观察者
class Observerd {
constructor(name){
this.name = name
this.state = "run..."
this.observer = []
}
//发送
setObserver(person){
this.observer.push(person)
}
//被观察者状态
setState(value){
this.state = value
this.observer.forEach(person =>{
person.update(this.name,this.state)
})
}
}
//观察者
class Observer {
constructor(name){
this.name = name
}
update(name,state){
console.log(name+"正在"+state)
}
}
</script>
</body>
</html>