使用 ES.later 的装饰器作为 mixin
function mixin (behaviour, sharedBehaviour = {}) {
const instanceKeys = Reflect.ownKeys(behaviour);
const sharedKeys = Reflect.ownKeys(sharedBehaviour);
const typeTag = Symbol('isa');
function _mixin (target) {
for (let property of instanceKeys)
Object.defineProperty(target, property, { value: behaviour[property] });
Object.defineProperty(target, typeTag, { value: true });
return target;
}
for (let property of sharedKeys)
Object.defineProperty(_mixin, property, {
value: sharedBehaviour[property],
enumerable: sharedBehaviour.propertyIsEnumerable(property)
});
Object.defineProperty(_mixin, Symbol.hasInstance, {
value: (i) => !!i[typeTag]
});
return _mixin;
}
const BookCollector = mixin({
addToCollection (name) {
this.collection().push(name);
return this;
},
collection () {
return this._collected_books || (this._collected_books = []);
}
});
class Person {
constructor (first, last) {
this.rename(first, last);
}
fullName () {
return this.firstName + " " + this.lastName;
}
rename (first, last) {
this.firstName = first;
this.lastName = last;
return this;
}
};
BookCollector(Person.prototype);
const president = new Person('Barak', 'Obama')
president
.addToCollection("JavaScript Allongé")
.addToCollection("Kestrels, Quirky Birds, and Hopeless Egocentricity");
president.collection()
//=> ["JavaScript Allongé","Kestrels, Quirky Birds, and Hopeless Egocentricity"]
只针对类的 mixin
function mixin (behaviour, sharedBehaviour = {}) {
const instanceKeys = Reflect.ownKeys(behaviour);
const sharedKeys = Reflect.ownKeys(sharedBehaviour);
const typeTag = Symbol('isa');
function _mixin (clazz) {
for (let property of instanceKeys)
Object.defineProperty(clazz.prototype, property, {
value: behaviour[property],
writable: true
});
Object.defineProperty(clazz.prototype, typeTag, { value: true });
return clazz;
}
for (let property of sharedKeys)
Object.defineProperty(_mixin, property, {
value: sharedBehaviour[property],
enumerable: sharedBehaviour.propertyIsEnumerable(property)
});
Object.defineProperty(_mixin, Symbol.hasInstance, {
value: (i) => !!i[typeTag]
});
return _mixin;
}
这一版的 _mixin 函数将实例行为糅合进类的原型,虽然没有支持任何对象那般的灵活,但是使用起来更方便:
const BookCollector = mixin({
addToCollection (name) {
this.collection().push(name);
return this;
},
collection () {
return this._collected_books || (this._collected_books = []);
}
});
class Person {
constructor (first, last) {
this.rename(first, last);
}
fullName () {
return this.firstName + " " + this.lastName;
}
rename (first, last) {
this.firstName = first;
this.lastName = last;
return this;
}
};
BookCollector(Person);
const president = new Person('Barak', 'Obama')
president
.addToCollection("JavaScript Allongé")
.addToCollection("Kestrels, Quirky Birds, and Hopeless Egocentricity");
president.collection()
//=> ["JavaScript Allongé","Kestrels, Quirky Birds, and Hopeless Egocentricity"]
至此,非常不错,但总觉得有点马后炮的感觉。我们可以利用一下“类即表达式”这一事实:
const BookCollector = mixin({
addToCollection (name) {
this.collection().push(name);
return this;
},
collection () {
return this._collected_books || (this._collected_books = []);
}
});
const Person = BookCollector(class {
constructor (first, last) {
this.rename(first, last);
}
fullName () {
return this.firstName + " " + this.lastName;
}
rename (first, last) {
this.firstName = first;
this.lastName = last;
return this;
}
});
const Author = mixin({
writeBook (name) {
this.books().push(name);
return this;
},
books () {
return this._books_written || (this._books_written = []);
}
});
const Person = Author(BookCollector(class {
// ...
}));
类装饰器
function annotation(target) {
// Add a property on target
target.annotated = true;
}
@annotation
class MyClass {
// ...
}
MyClass.annotated
//=> true
const BookCollector = mixin({
addToCollection (name) {
this.collection().push(name);
return this;
},
collection () {
return this._collected_books || (this._collected_books = []);
}
});
@BookCollector
class Person {
constructor (first, last) {
this.rename(first, last);
}
fullName () {
return this.firstName + " " + this.lastName;
}
rename (first, last) {
this.firstName = first;
this.lastName = last;
return this;
}
};
const president = new Person('Barak', 'Obama')
president
.addToCollection("JavaScript Allongé")
.addToCollection("Kestrels, Quirky Birds, and Hopeless Egocentricity");
president.collection()
//=> ["JavaScript Allongé","Kestrels, Quirky Birds, and Hopeless Egocentricity"]
const BookCollector = mixin({
addToCollection (name) {
this.collection().push(name);
return this;
},
collection () {
return this._collected_books || (this._collected_books = []);
}
});
const Author = mixin({
writeBook (name) {
this.books().push(name);
return this;
},
books () {
return this._books_written || (this._books_written = []);
}
});
@BookCollector @Author
class Person {
constructor (first, last) {
this.rename(first, last);
}
fullName () {
return this.firstName + " " + this.lastName;
}
rename (first, last) {
this.firstName = first;
this.lastName = last;
return this;
}
};
如果你想使用装饰器模拟“纯函数式复合”,这也是简单易行的惯常模式:
class Person {
constructor (first, last) {
this.rename(first, last);
}
fullName () {
return this.firstName + " " + this.lastName;
}
rename (first, last) {
this.firstName = first;
this.lastName = last;
return this;
}
};
@BookCollector @Author
class BookLover extends Person {};
使用装饰器
使用 ES.later 的装饰器作为 mixin的更多相关文章
- python装饰器、继承、元类、mixin,四种給类动态添加类属性和方法的方式(一)
介绍装饰器.继承.元类.mixin,四种給类动态添加类属性和方法的方式 有时候需要給类添加额外的东西,有些东西很频繁,每个类都需要,如果不想反复的复制粘贴到每个类,可以动态添加. # coding=u ...
- ES 6 装饰器与 React 高阶组件
关于 Decorator 到底是 ES 6 引入的还是 ES 7 引入的我也不是很明白了,两种说法都有,这种问题懒得纠结了--在用的时候发现这个东西很好用,平常用处可能不大,但是结合 React 就很 ...
- ES6 系列之我们来聊聊装饰器
Decorator 装饰器主要用于: 装饰类 装饰方法或属性 装饰类 @annotation class MyClass { } function annotation(target) { targe ...
- guxh的python笔记三:装饰器
1,函数作用域 这种情况可以顺利执行: total = 0 def run(): print(total) 这种情况会报错: total = 0 def run(): print(total) tot ...
- 面向切面编程AOP,一些通用装饰器
1.一些装饰器,可以减少重复编写.比较常用的. 用的时候函数上面加上装饰器就可以.这是一些装饰器,加在函数或者方法上,减少了很多重复代码. 除此之外工作中也用一些mixin类大幅减少代码. impor ...
- es7 class装饰器
文档http://es6.ruanyifeng.com/#docs/decorator ts文档 https://www.tslang.cn/docs/handbook/decorators.html ...
- Javascript装饰器的妙用
最近新开了一个Node项目,采用TypeScript来开发,在数据库及路由管理方面用了不少的装饰器,发觉这的确是一个好东西.装饰器是一个还处于草案中的特性,目前木有直接支持该语法的环境,但是可以通过 ...
- 巨蟒python全栈开发django5:组件&&CBV&FBV&&装饰器&&ORM增删改查
内容回顾: 补充反向解析 Html:{% url ‘别名’ 参数 %} Views:reverse(‘别名’,args=(参数,)) 模板渲染 变量 {{ 变量名 }} 逻辑相关 {% %} 过滤器: ...
- TypeScript 装饰器
装饰器(Decorators)可用来装饰类,属性,及方法,甚至是函数的参数,以改变和控制这些对象的表现,获得一些功能. 装饰器以 @expression 形式呈现在被装饰对象的前面或者上方,其中 ex ...
随机推荐
- 解决ajax跨域访问sessionid不一致问题
根据浏览器的保护规则,跨域的时候我们创建的sessionId是不会被浏览器保存下来的,这样,当我们在进行跨域访问的时候,我们的sessionId就不会被保存下来,也就是说,每一次的请求,服务器就会以为 ...
- Linux(二)—— Unix&Linux 的基本概念
Linux(二)-- Unix&Linux 的基本概念 计算机 = 主机(host)+ 终端(terminal) 主机 = 内核 + 实用工具 内核(kernel) 当计算机启动时,计算机要经 ...
- mongodb复制+分片集原理
----------------------------------------复制集---------------------------------------- 一.复制集概述: Mongodb ...
- memcached架构及缓存策略
----------------------------------------概述---------------------------------------- Memcached是一套高性能分布 ...
- socket.io 出现的WebSocket is closed before the connection is established
WebSocket is closed before the connection is established 最近socket.io是挺流行的,幼麟棋牌和一些好的开源项目也使用这个框架,在搭建其平 ...
- 数据库【mongodb篇】练习操作
本文的目标是通过大量的示例,来更好的理解如果在Mongodb中进行数据操作: 初入客户端刚利用 mongod命令进入客户端环境,此时对数据库一无所知: 举目四望,想知道现在有哪些数据库, show ...
- Kafka Tuning Recommendations
Kafka Brokers per Server Recommend 1 Kafka broker per server- Kafka not only disk-intensive but can ...
- KL散度、JS散度、Wasserstein距离
1. KL散度 KL散度又称为相对熵,信息散度,信息增益.KL散度是是两个概率分布 $P$ 和 $Q$ 之间差别的非对称性的度量. KL散度是用来 度量使用基于 $Q$ 的编码来编码来自 $P$ 的 ...
- 是时候理解下HTTPS的原理及流程了
1.什么是HTTP协议? HTTP协议是Hyper Text Transfer Protocol(超文本传输协议),位于TCP/IP模型当中的应用层.HTTP协议通过请求/响应的方式,在客户端和服务端 ...
- python科学计算库的numpy基础知识,完美抽象多维数组(原创)
#导入科学计算库 #起别名避免重名 import numpy as np #小技巧:从外往内看==从左往右看 从内往外看==从右往左看 #打印版本号 print(np.version.version) ...