前端设计模式总结

1)观察者模式和发布/订阅模式真不一样

发布订阅模式

var pubsub = (()=>{ var topics = {}; //内部存储对象

function subscribe(topic,fn){ //订阅

if(!topics[topic]){

topics[topic] = [];

}

topics[topic].push(fn); //存储

}

function publish(topic,...args){ //共享存储对象,发布

if(!topics[topic])

return;

for(let fn of topics[topic]){ //遍历依次执行

fn(...args);

} }

return

{

subscribe, //暴露方法

publish

} })()

测试代码

pubsub.subscribe('test',function(a,b){ //订阅者A订阅了test事件 console.log(a,b); }); pubsub.publish('test','123','HH'); //123 HH(发布者B发布了test事件)


上面的例子是发布订阅模式。订阅者A和发布者B是通过pubsub这个对象关联起来的,他们没有直接的交流。A \B中去使用pubsub这个对象,和AB本身是无关联的。

实现下观察者模式。

首先是目标的构造函数,他有个数组,用于添加观察者。还有个广播方法,遍历观察者数组后调用他们的update方法:

class Subject{

constructor(){

this.subs = []; }

addSub(sub){ //‘订阅’

this.subs.push(sub);

}

notify(){ //‘发布’

this.subs.forEach(sub=> { sub.update(); });

} }

那么观察者就得有个update方法:

class Observer{

update(){ console.log('update'); }

}

测试代码

let subject = new Subject(); let ob = new Observer();

//目标添加观察者了 subject.addSub(ob);

//目标发布消息调用观察者的更新方法了 subject.notify(); //update

观察者模式:定义了对象间一种一对多的依赖关系,当目标对象 Subject 的状态发生改变时,所有依赖它的对象 Observer 都会得到通知。

模式特征以及角色:

  1. 一个目标者对象 Subject,拥有方法:添加 / 删除 / 通知 Observer;
  2. 多个观察者对象 Observer,拥有方法:接收 Subject 状态变更通知并处理;
  3. 目标对象 Subject 状态变更时,通知所有 Observer。

Subject 可以添加一系列 Observer, Subject 负责维护与这些 Observer 之间的联系,“你对我有兴趣,我更新就会通知你”。

Subject - 被观察者,发布者;

Observer - 观察者,订阅者;

// 目标者

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 o of this.observers) {

o.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();

subject 被观察 (订、取消。通知) Observer观察者(处理消息的回调)

发布订阅模式

/ 控制中心

let pubSub = {

list: {},

// 订阅

subscribe: function(key, fn) {

if (!this.list[key]) this.list[key] = [];

this.list[key].push(fn);

},

//取消订阅

unsubscribe: function(key, fn) {

let fnList = this.list[key];

if (!fnList) return false;

if (!fn) { // 不传入指定的方法,清空所用 key 下的订阅

fnList && (fnList.length = 0);

} else {

fnList.forEach((item, index) => {

item === fn && fnList.splice(index, 1);

});

}

},

// 发布

publish: function(key, ...args) {

for (let fn of this.list[key]) fn.call(this, ...args);

}

}

// 订阅

pubSub.subscribe('onwork', time => {

console.log(`上班了:${time}`);

})

pubSub.subscribe('offwork', time => {

console.log(`下班了:${time}`);

})

pubSub.subscribe('launch', time => {

console.log(`吃饭了:${time}`);

})

pubSub.subscribe('onwork', work => {

console.log(`上班了:${work}`);

})

// 发布

pubSub.publish('offwork', '18:00:00');

pubSub.publish('launch', '12:00:00');

// 取消订阅

pubSub.unsubscribe('onwork');

优缺点:

优点:解耦更好,细粒度更容易掌控;

缺点:不易阅读,额外对象创建,消耗时间和内存(很多设计模式的通病)

两种模式的关联和区别

发布订阅模式更灵活,是进阶版的观察者模式,指定对应分发。

  1. 观察者模式维护单一事件对应多个依赖该事件的对象关系;
  2. 发布订阅维护多个事件(主题)及依赖各事件(主题)的对象之间的关系;
  3. 观察者模式是目标对象直接触发通知(全部通知),观察对象被迫接收通知。发布订阅模式多了个中间层(事件中心),由其去管理通知广播(只通知订阅对应事件的对象);
  4. 观察者模式对象间依赖关系较强,发布订阅模式中对象之间实现真正的解耦。

2)认证-彻底搞懂 Cookie、Session、Token、JWT

路径不同不属于跨域

三、非同源限制

【1】无法读取非同源网页的 Cookie、LocalStorage 和 IndexedDB

【2】无法接触非同源网页的 DOM

【3】无法向非同源地址发送 AJAX 请求

cookie 一般都是由于用户访问页面而被创建的,可是并不是只有在创建 cookie 的页面才可以访问这个cookie。在默认情况下,出于安全方面的考虑,只有与创建 cookie 的页面处于同一个目录或在创建cookie页面的子目录下的网页才可以访问。那么此时如果希望其父级或者整个网页都能够使用cookie,就需要进行路径的设置。

path表示cookie所在的目录,asp.net默认为/,就是根目录。在同一个服务器上有目录如下:/test/,/test/cd/,/test/dd/,现设一个cookie1的path为/test/cookie2的path为/test/cd/,那么test下的所有页面都可以访问到cookie1,而/test/和/test/dd/的子页面不能访问cookie2。这是因为cookie能让其path路径下的页面访问。

让这个设置的cookie 能被其他目录或者父级的目录访问的方法:

 document.cookie = "name = value; path=/";

domain表示的是cookie所在的域,默认为请求的地址,如网址为www.jb51.net/test/test.aspx,那么domain默认为www.jb51.net。而跨域访问,如域A为t1.test.com,域B为t2.test.com,那么在域A生产一个令域A和域B都能访问的cookie就要将该cookie的domain设置为.test.com;如果要在域A生产一个令域A不能访问而域B能访问的cookie就要将该cookie的domain设置为t2.test.com。

  • 20
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nicky_hb

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值