文章目录
-
-
-
-
-
- 实现一下观察者模式
- 实现一下工厂模式
- 实现一下单例模式
- 设计一个lazyMan,实现以下功能:
- 实现一个简单的EventEmitter
- 手撕实现原生js的一些方法(call、apply、bind、map、reduce、filter、splice、pop、push、unshift、shift)
- 实现对象的迭代器,使得对象可以使用for of方式循环
- 手撕实现一下前端路由
- 简单实现一下实现事件委托(ul中很多个li标签)
- 用setTimeOut实现一下setInterval
- 实现一下curry函数(柯里化函数)
- 实现类似 add(1)(2) add(1, 2, 3)(10) add(1)(2)(3)(4)(5)的函数
- 实现一下es5的几种继承方法
- 代码实现一下new方法过程
- 简单实现promise方法
- 实现promise.all和promise.race
- 实现promise.allsettled 和 promise.any
- 实现一个promise失败重传函数(重传限定多少次)
- 实现一个串行执行的promise
- 实现一个并发控制数量的promise
- 实现一个基于promise的ajax函数
- 实现一个深拷贝函数
- 用函数实现一下instanceof和typeof的功能
- 实现防抖和节流函数
- 实现数组扁平化函数flatten
- 创建形如a.b.c.d嵌套对象
- 二叉树的前中后序(深度优先)及层序(广度优先)遍历
- 实现以下lodash的_get()函数
- 实现将url中?后的参数转化为js对象
- 实现大数相加
- 字符串的全排列
- 多维数组的全排列
- 判断是否为平衡二叉树
- 两数之和、三数之和
-
-
-
-
实现一下观察者模式
class Subject {
constructor () {
this.state = 0
this.observe = []
}
getState () {
return this.state
}
setState (val) {
this.state = val
this.observe.forEach((item) => {
item.update()
})
}
attach(ob) {
this.observe.push(ob)
}
}
class Observe {
constructor (name, sub) {
this.name = name
this.sub = sub
this.sub.attach(this)
}
update () {
console.log(`${
this.name} update, state: ${
this.sub.getState()}`)
}
}
实现一下工厂模式
// 工厂模式
class Role {
constructor(options) {
this.role = options.role;
this.permissions = options.permissions;
}
show() {
const str = `是一个${
this.role}, 权限:${
this.permissions.join(', ')}`;
console.log(str);
}
}
class SimpleFactory {
constructor(role) {
if(typeof this[role] !== 'function') {
throw new Error('参数只能为 admin 或 developer');
}
return this[role]();
}
admin() {
return new Role({
role: '管理员',
permissions: ['设置', '删除', '新增', '创建', '开发', '推送', '提问', '评论']
});
}
developer() {
return new Role({
role: '开发者',
permissions: ['开发', '推送', '提问', '评论']
});
}
}
实现一下单例模式
class LoginForm {
constructor () {
this.state = 'hide'
}
show () {
if (this.state === 'show') {
console.log('已经show')
}
this.state = 'show'
console.log('登录框show成功')
}
hide () {
if (this.state === 'hide') {
console.log('已经hide')
}
this.state = 'hide'
console.log('登录框hide成功')
}
}
LoginForm.getInstance = (function () {
let instance = null
return function () {
if (!instance) {
instance = new LoginForm()
}
return instance
}
})()
设计一个lazyMan,实现以下功能:
LazyMan(‘Tony’);
// Hi I am TonyLazyMan(‘Tony’).sleep(10).eat(‘lunch’);
// Hi I am Tony
// 等待了10秒…
// I am eating lunch
LazyMan(‘Tony’).eat(‘lunch’).sleep(10).eat(‘dinner’);
// Hi I am Tony
// I am eating lunch
// 等待了10秒…
// I am eating diner
LazyMan(‘Tony’).eat(‘lunch’).eat(‘dinner’).sleepFirst(5).sleep(10).eat(‘junk food’);
// Hi I am Tony
// 等待了5秒…
// I am eating lunch
// I am eating dinner
// 等待了10秒…
// I am eating junk food
考察点:运用发布订阅者模式,js事件执行机制
function lazyMan(name) {
// 任务清单队列
this.taskList = []
this.name = name
console.log(`Hi I am ${
name}`)
setTimeout(() => this.next())
}
lazyMan.prototype = {
// 订阅方法
eat (food) {
const fn = () => {
console.log(`i am eating ${
food}`);
this.next()
}
this.taskList.push(fn)
return this
},
sleepFirst (time) {
const fn = () => {
setTimeout(() => {
console.log(`等待了${
time}秒`);
this.next()
}, time*1000)
}
this.taskList.unshift(fn)
return this
},
sleep (time) {
const fn = () => {
setTimeout(() => {
console.log(`等待了${
time}秒`);
this.next()
}, time*1000)
}
this.taskList.push(fn)
return this
},
// 事件发布
next () {
const fn = this.taskList.shift()
fn && fn()
}
}
function LazyMan (name) {
return new lazyMan(name)
}
LazyMan('Tony')
LazyMan('Tony').sleep(10).eat('lunch')
LazyMan('Tony').eat('lunch').sleep(10).eat('dinner')
LazyMan('Tony').eat('lunch').eat('dinner').sleepFirst(5).sleep(10).eat('junk food')
实现一个简单的EventEmitter
就是事件的触发机制,发布订阅者的一个实现,和上题思路一样
function eventEmitter () {
// 定义事件池
this.eventpool = {
}
// 事件绑定
this.on = function (event, callback) {
this.eventpool[event] ? this.eventpool[event].push(callback) : this.eventpool[event]
}
// 事件分发
this.emit = function (event, ...args) {
this.eventpool[event] && this.eventpool[event].forEach((cb) => cb(...args))
}
// 事件解绑
this.off (event) {
if (this.eventpool[event]) {
delete this.eventpool[event]
}
}
// 事件只绑定执行一次
this.once(event, callback) {
this.on(event, (...args) => {
callback(...args)
this.off(event)
})
}
}
考察点:事件触发与事件监听器功能的封装
以上两个手撕题涉及的
发布 + 订阅:
DOM 的事件机制就是发布订阅模式最常见的实现,这大概是前端最常用的编程模型了,监听某事件,当该事件发生时,监听该事件的监听函数被调用。
————————————————————————————————————
发布订阅模式,阮一峰在《Javascript 异步编程的 4 种方法》,中:我们假定,存在一个"信号中心",某个任务执行完成,就向信号中心"发布"(publish)一个信号,其他任务可以向信号中心"订阅"(subscribe)这个信号,从而知道什么时候自己可以开始执行。这就叫做"发布/订阅模式"(publish-subscribe
pattern),又称"观察者模式"(observer pattern)。
手撕实现原生js的一些方法(call、apply、bind、map、reduce、filter、splice、pop、push、unshift、shift)
- 实现call方法
// call的实现(实现call)
Function.prototype.call = function (context) {
context = context ? Object(context) : window
context.fn = this
let args = [...arguments].slice(1)
let res = context.fn(...args)
delete context.fn
return res
}
- 实现apply方法
// apply的实现
Function.prototype.apply = function (context, arr) {
context = context ? Object(context) : window
context.fn = this
let res
if (!arr) {
res = context.fn()
} else {
res = context.fn(...arr)
}
delete context.fn
return res
}
- 实现bind方法
// 函数实现
function bind(fn, context) {
let args = Array.prototype.slice.call(arguments, 2)
return function () {
return fn.apply(context, args.concat(Array.prototype.slice.call(arguments)))
}
}
// 原型链修改
Function.prototype.bind = function (context) {
let that = this
let args = Array.prototype.slice.call(arguments, 1)
return function () {
return that.apply(context, args.concat(Array.prototype.slice.call(arguments)))
}
}
// 更为完整的方法
Function.prototype.bind2 = function (context) {
if (typeof this !== "function") {
throw new Error("Function.prototype.bind - what is trying to be bound is not callable");
}
var self = this;
var args = Array.prototype.slice.call(arguments, 1);
var fNOP = function () {
};
var fBound = function ()