使用Proxy实现观察者模式
const queueObservers = new Set();
const observers = (fn) => queueObservers.add(fn);
const observable = (obj) =>
new Proxy(obj, {
set(target, key, value, receiver) {
Reflect.set(target, key, value);
queueObservers.forEach((fn) => fn());
},
get(target, key, receiver) {
queueObservers.forEach((fn) => fn());
return Reflect.get(target, key);
},
});
observers(function () {
console.log('开始观察');
});
const person = observable({
name: '张三',
age: 18,
});
person.name = '刘武';
console.log(person.name);
使用proxy实现数组读取负数的索引
const readArray = (arr) =>
new Proxy(arr, {
set(target, key, value, receiver) {
if (Number(key) < 0) {
Reflect.set(target, Number(key) + target.length, value);
} else {
Reflect.set(target, key, value);
}
},
get(target, key, receiver) {
console.log(Number(key))
if (Number(key) < 0) {
return Reflect.get(target, Number(key) + target.length);
} else {
return Reflect.get(target, key);
}
},
});
const arr = readArray([1, 2, 4, 5, 6, 7]);
console.log(arr[2]);
const obj = readArray({
name:'1'})
console.log(obj.name)
实现生成各种 DOM 节点的通用函数
const createDom = new Proxy(
{
},
{
get(target, tag) {
return function (attrs = {
}, ...children) {
const el = document.createElement(tag);
for (key in attrs) {
el.setAttribute(key, attrs[key]);
}
for (let child of children) {
if (typeof child == 'string') {
child = document.createTextNode(child);
}
el.appendChild(child);
}
return el;
};
},
},
);
const el = createDom.div(
{
style:
'width: 600px;height: 200px;border: 1px solid #000;text-align: center;line-height: 200px;',
},
'去百度',
createDom.a({
href: 'https://www.baidu.com' }, '百度'),
);
document.body.appendChild(el);
reduce
const double = (x) => x + x;
const triple = (x) => 3 * x;
const quadruple = (x) => 4 * x;
const pipe = (...functions) => (input) => functions.reduce((acc, fn) => fn(acc), input);
const multiply6 = pipe(double, triple);
multiply6(6);
将读取属性的操作(get),转变为执行某个函数,从而实现属性的链式操作
const pipe = function (value) {
const funcStack = [];
const proxy = new Proxy(
{
},
{
get(target, key) {
if (key === 'get') {
return funcStack.reduce(function (val, fn) {
return fn(val);
}, value);
}
funcStack.push(window[key]);
return proxy;
},
},
);
return proxy;
};
var double = (n) => n * 2;
var pow = (n) => n * n;
const a = pipe(3).double.pow.get;
console.log(a);