Javascript 进阶
封装(订阅者 + 发布者)
提出问题
问题描述:假如我是一个推销产品的应用开发经理,有很多的用户在我的平台上订阅些内容,我如何通过用户订阅的信息,准确的发送产品给需要它的客户们呢?
分析问题
- 首先我是卖家,我需要提供一个添加订阅信息和对应的用户功能函数
- 当我发布一个产品的时候,我需要精准的发送给需要它的用户
步骤
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| var seller = {};
seller.list = [];
seller.listen = (fn) => seller.list.push(fn);
seller.trigger = function () { for (var i = 0, fn; (fn = this.list[i]); i++) { fn.call(this, ...arguments); } };
seller.listen(function (color, size) { console.log("我是A订阅者"); console.log("您订阅的卖家发布新的鞋:"); console.log("颜色是:", color); console.log("尺寸是:", size); });
seller.listen(function (color, size) { console.log("我是B订阅者"); console.log("您订阅的卖家发布新的鞋:"); console.log("颜色是:", color); console.log("尺寸是:", size); });
seller.trigger("红色", 42);
|
这样一个简单的发布过程就做好了,然而这并不是定制,因为每次发布一个产品,都要通知所有的订阅者,我们的目的是通过订阅者订阅的关键字,来精准的发布产品给有需要的客户,这次我们用对象来写
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
| var method1 = { list: [],
listen(key, user) { if (!this.list[key]) { this.list[key] = []; } this.list[key].push(user); },
trigger() { let key = Array.prototype.shift.call(arguments);
let user = this.list[key]; if (!user || user.length === 0) { return; }
for (let i = 0, each; (each = user[i++]); ) { each(...arguments); } }, };
var init = function (obj) { for (var key in method1) { obj[key] = method1[key]; } };
var seller = {}; init(seller);
seller.listen("显卡", function (msg) { console.log("我是订阅者A,订阅:显卡,价格为:", msg); console.log("\n"); });
seller.listen("电脑", function (msg) { console.log("我是订阅者B,订阅:电脑,价格为:", msg); console.log("\n"); });
seller.listen("手机", function (msg) { console.log("我是订阅者C,订阅:手机,价格为:", msg); console.log("\n"); });
seller.trigger("显卡", 2499); seller.trigger("棒槌", 2499); seller.trigger("手机", 999);
|
总结问题
- 通过上面的案例,稍微体验了一下封装是什么样的感觉,类似大的插件也是这样的思想,封装对于大厂用途比较多。
- 尽量的体会过程!!!
深复制 & 浅复制
- 深复制:深拷贝会开辟新的栈内存,原对象和新对象不共享同一块内存,修改新对象不会影响到原对象。
- 浅复制:复制指向,引用。
- object.assign()
- slice
- concat
内存
js 中,内存是自动分配的,当变量不再需要的时候自动释放,过程如下:
- 分配需要的内存空间
- 使用分配的内存(读写)
- 不需要时释放或者归还 gc(垃圾回收机制)
内存泄露
不再需要此内存,然而由于某种原因,无法释放此内存。
- 全局变量带来的
- 回调函数
function a(){
return 2;
}
var b = a()
- 额外的定时器
- dom 引用(removeChild 后,还能获得节点的信息)
- 闭包也会出现内存泄漏(优点是防止全局变量污染)
垃圾回收机制 GC
垃圾回收的方法分两种,
- 引用计数:统计被引用的次数,次数为 0,被回收。
- 标记清除
分类
- 栈:用来存放基本数据类型,还有指向复杂数据类型的引用指针
- 堆:用来存放复杂数据类型,这种数据结构是一种无序的树状,通过
key
来保存指针,类似字典。
- 队列:先进先出,典型的例子是 JS 中的事件循环(
eventsloop
)
- 池
this**
我的 this 详解。