最近刷一些笔试题,巩固一下基础,做一个笔记,随着做题进度,也会持续更新,欢迎指正
1、实现一个深拷贝
function copyObj(obj) {
let cloneObj
if (obj && typeof obj !== 'object') {
cloneObj = obj
}
else if (obj && typeof obj === 'object') {
cloneObj = Array.isArray(obj) ? [] : {}
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
if (obj[key] && typeof obj[key] === 'object') {
cloneObj[key] = copyObj(obj[key])
}
else {
cloneObj[key] = obj[key]
}
}
}
}
return cloneObj
}
2、简单的发布订阅模式 和观察者模式
class EventClass {
_events = {}
on = (key, callBack) => {
if (!this._events[key]) {
this._events[key] = []
}
this._events[key].push(callBack)
}
emit = (key, ...args) => {
this._events[key].forEach((callBack) => {
callBack(...args)
})
}
off(key, callBack) {
this._events[key] = this._events[key].map((item) => {
return item !== callBack
})
}
once(key, callback) {
const once = (...args) => {
callback(...args)
this.off(key, once)
}
this.on(key, once)
}
}
class Subject {
constructor() {
this.observers = [];
}
add(observer) {
this.observers.push(observer);
}
remove(observer) {
let idx = this.observers.findIndex(item => item === observer);
idx > -1 && this.observers.splice(idx, 1);
}
notify() {
for (let observer of this.observers) {
observer.update();
}
}
}
class Observer {
constructor(name) {
this.name = name;
}
update() {
console.log(`目标者通知我更新了,我是:${this.name}`);
}
}
let subject = new Subject();
let obs1 = new Observer('前端开发者');
let obs2 = new Observer('后端开发者');
subject.add(obs1);
subject.add(obs2);
subject.notify();
3、单例模式
class Single {
oneSingle = ''
static installSingle = () => {
if (!this.oneSingle) {
this.oneSingle = new Single()
return this.oneSingle
}
return this.oneSingle
}
}
4、工厂模式-传入参数即可创建实例
function Employee(name) {
this.name = name;
this.say = function () {
console.log('I am employee ' + name);
};
}
function EmployeeFactory() {
this.create = function (name) {
return new Employee(name);
};
}
let persons = [];
const employeeFactory = new EmployeeFactory();
persons.push(employeeFactory.create('jake'));
persons.push(employeeFactory.create('rabin'));
persons.forEach(item => {
item.say();
});
function Vendor(name) {
this.name = name;
this.say = function () {
console.log('I am Vendor ' + name);
};
}
function vendorFun() {
return function (name) {
return new Vendor(name);
};
}
const vendorFactory = vendorFun();
let vendors = [];
vendors.push(vendorFactory('jake'));
vendors.push(vendorFactory('rabin'));
vendors.forEach(item => {
item.say();
});
5、装饰器的用法
- AOP(面向切面编程)的主要作用是把一些跟核心业务逻辑模块无关的功能抽离出来,这些跟业务逻辑无关的功能通常包括日志统计、安全控制、异常处理等。把这些功能抽离出来之后, 再通过“动态织入”的方式掺入业务逻辑模块中。
- AOP的好处首先是可以保持业务逻辑模块的纯净和高内聚性,其次是可以很方便地复用日志统计等功能模块。
- 在 JavaScript 中实现 AOP,都是指把一个函数“动态织入”到另外一个函数之中
function say(a,b){
console.log('say',a,b);
}
Function.prototype.before = function (callback) {
return (...args)=>{
callback();
this(...args);
}
}
let beforeSay = say.before(function(){
console.log('before say')
})
beforeSay('hello','world');
- 装饰者(decorator)模式能够在不改变对象自身的基础上,动态的给某个对象添加额外的职责,不会影响原有接口的功能。
class Person {
name: string;
constructor(name:string) {
this.name = name;
}
@fun(false)
static say() {
return "hello" + this.name
}
}
function fun(value: boolean) {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
console.log("target",target);
console.log("propertyKey",propertyKey);
descriptor.enumerable = value
console.log(descriptor);
}
}
const p = new Person("zhangsan")
6、手写instanceof 的实现
function instance_of(L,R){
const baseType = ['string', 'number','boolean','undefined','symbol']
if(baseType.includes(typeof(L))) { return false }
let RP = R.prototype;
L = L.__proto__;
while(true){
if(L === null){
return false;
}
if(L === RP){
return true;
}
L = L.__proto__;
}
}