掺合模式(Mixin)
Mixin是JavaScript中用的最普遍的模式,可以就任意一个对象的全部或部分属性拷贝到另一个对象上。从提供的接口来看,有的是对对象的操作,有的是对类的操作。对类的操作又称为掺元类(Mixin classes)几乎所有流行类库都会有Mixin的实现。
比如说:
jQuery的$.extend 操作对象,将其它对象的属性方法拷贝到目标对象。
RequireJS的私有的mixin 操作对象,将其它对象的属性方法拷贝到目标对象。
Underscore.js 的 _.extend,把第二个参数起的所有对象都拷贝到第一个参数
1.掺合对象 (Mixin object)
先看最简单的mixin实现
function mixin(dest, src) {
for (var key in src) {
dest[key] = src[key]
}
}
//使用下
var person = {name: 'yudi', age: 24}
var obj = {}
mixin(obj, person)
console.log(obj) // {name: 'yudi', age: 24}
上面的已经将person的所有属性拷贝到obj上了。 但有个缺陷,如果obj上已经有了name: 'rain',那么会被person覆盖。因此需要加个判断,如果dest上已经存在了,就不拷贝。
function mixin(dest, src) {
for (var key in src) {
if (!dest[key]) {
dest[key] = src[key]
}
}
}
//使用
var person = {name: 'yudi', age: 24}
var obj = {name: 'rain'}
mixin(obj, person)
console.log(obj) // Object { name="yudi", age=24}
当然,你可以提供更强大,灵活的Mixin,比如可以将任意多个对象掺合到目标对象
function mixin(dest /*, Any number of objects */) {
var sources = Array.prototype.slice.call(arguments, 1)
for (var i=0; i<sources.length; i++) {
var src = sources[i]
for (var key in src) {
if (!dest[key]) {
dest[key] = src[key]
}
}
}
}
//使用
var person = {name: 'John', age: 29, toString: function(){return 'aa'}}
var permission = {open: 1}
var obj = {name: 'Jack'}
mixin(obj, person, permission)
console.log(obj) // Object { name="Jack", age=29, open=1}
2.掺和类(Mixin Classes)
有的翻译过来叫做掺元类,它是一种不需要用到严格的继承就可以复用代码的一种技术。如果多个类想用到某个类的某个方法,可以通过扩充这些类的原型已达到共享该方法。比如先创建一个包含各种通用方法的类,然后让其它类扩充于它。这个包含通用方法的类就叫掺元类。多数时候它不会直接实例化或调用,而是作为其它类的模板用于扩充。
先看最简单的实现
// 工具方法,实现mixin
function augment(destClass, srcClass) {
var destProto = destClass.prototype
var srcProto = srcClass.prototype
for (var method in srcProto) {
if (!destProto[method]) {
destProto[method] = srcProto[method]
}
}
} function Person() {} // 具有两个方法的类,用于mixin
Person.prototype.getName = function() {}
Person.prototype.getAge = function() {} function Student() {} // 没有任何方法的类 augment(Student, Person) // 调用,拷贝 var s1 = new Student()
console.log(s1) // Student { getName=function(), getAge=function()}
工具函数augment接受两个参数,都是函数类型(类),第一个类会从第二个类的原型上继承其方法。即使用Person类扩充了Student类。
我们知道,某些语言如C++/Python允许子类继承多个父类,但在JavaScript中是不允许的,因为一个构造器只有一个原型对象,不过这可以通过多个掺元类的方式实现扩充,这实际是一种变相多继承的实现。和mixin方法类似,修改下augment方法。
function augment(destClass, /*, Any number of classes */) {
var classes = Array.prototype.slice.call(arguments, 1)
for (var i=0; i<classes.length; i++) {
var srcClass = classes[i]
var srcProto = srcClass.prototype
var destProto = destClass.prototype
for (var method in srcProto) {
if (!destProto[method]) {
destProto[method] = srcProto[method]
}
}
}
}
//这样就实现了多继承。
有时不想继承所有的方法,指向拷贝指定的方法,增加一个参数methods
function augment(destClass, srcClass, methods) {
var srcProto = srcClass.prototype
var destProto = destClass.prototype
for (var i=0; i<methods.length; i++) {
var method = methods[i]
if (!destProto[method]) {
destProto[method] = srcProto[method]
}
}
}
function Person() {}
Person.prototype.getName = function() {}
Person.prototype.setName = function() {}
Person.prototype.getAge = function() {}
Person.prototype.setAge = function() {}
function Student() {}
augment(Student, Person, ['getName', 'setName'])
var s1 = new Student()
console.log(s1) // Student { getName=function(), setName=function()}
掺合模式(Mixin)的更多相关文章
- javascript模式——Mixin
Mixin是一种扩展收集功能的方式,能提高代码的复用率. 在javascript中,原型可以继承于其它对象的原型,并且可以为任意数量的实例定义属性.可以利用这一点来促进函数的复用. 下面一段代码就是将 ...
- Matlab混入模式(Mixin)
Mixin是一种类,这种类包含了其他类要使用的特性方法,但不必充当其他类的父类.Matlab无疑是支持多继承的.我们可以利用 Matlab 的这种特性,实现一种叫做 Mixin 的类.MixIn的目的 ...
- Mixin模式
Mixin是JavaScript中用的最普遍的模式,几乎所有流行类库都会有Mixin的实现. Mixin是掺合,混合,糅合的意思,即可以就任意一个对象的全部或部分属性拷贝到另一个对象上. 从提供的接口 ...
- 设计模式 Mixin (混入类)
混入(mix-in)类代表类之间的另一种关系.在C++中,混入类的语法类似于多重继承,但是语义完全不同.混入类回答"这个类还可以做什么"这个问题,答案经常以"-able& ...
- Python的Mixin
转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/10826299.html 一:Mixin模式 Mixin编程是一种开发模式,是一种 将多个不同类中的功能单元的 ...
- Python SocketServer源码分析
1 XXXServer 1.1 BaseSever 提供基础的循环等待请求的处理框架.使用serve_forever启动服务,使用shutdown停止.同时提供了一些可自行扩展的方 ...
- JavaScript的学习--JavaScript设计模式的总结
这篇博客只是自己对设计模式的理解的备忘~ 看完了<JavaScript设计模式>这本书,一直没有写博客记录一下,最近抽出时间来重读了一下,就顺便记录一下~ 如果你只是想粗略了解一下Java ...
- ES6(六) --- Symbol
概述: ES5 中属性名都是字符串,这容易就造成命名的冲突,特别是在混入模式(mixin模式)下.为解决这个问题ES6 引入了Symbol, Symbol是一种新的基本数据类型,表示独一无二的值! ...
- Python设计模式 - 基础 - 封装 & 继承 & 多态
面向对象的核心是对象,世间万物都可以看作对象,任何一个对象都可以通过一系列属性和行为来描述,可以包含任意数量和类型的数据或操作.类是用来描述具有相同属性和方法的所有对象的集合.类通常是抽象化的概念,而 ...
随机推荐
- 网站SEO优化
网站的优化应该迎合搜索引擎,这样才能得到事半功倍的效果! 一.站内优化 1.做好HTML头标签 标题(title):标题是网页优化中相当有分量,一般网页title主要包含一些关键词.网站名称等.关键词 ...
- 四层协议和Socket编程
<四层协议图> <Soclet编程模型图>
- VC 在调用main函数之前的操作
title: VC 在调用main函数之前的操作 tags: [VC++, 反汇编, C++实现原理] date: 2018-09-16 10:36:23 categories: VC++反汇编分析 ...
- sql: TRIGGER
--Common Table Expressions(CTE) WITH HighSample (SampleId,SampleTitle,SampleContent) AS ( SELECT Sam ...
- JavaWeb请求-响应学习笔记
先来看一个流程图: 服务器处理请求的流程: (1)服务器每次收到请求时,都会为这个请求开辟一个新的线程. (2)服务器会把客户端的请求数据封装到request对象中,request就是请求数据的载 ...
- RocketMQ读书笔记3——消费者
[不同类型的消费者] DefaultMQPushConsumer 由系统控制读取操作,收到消息后自动调用传入的处理方法来处理. DefaultMQPullConsumer 读取操作中的大部分功能由使用 ...
- Python爬虫教程-19-数据提取-正则表达式(re)
本篇主页内容:match的基本使用,search的基本使用,findall,finditer的基本使用,匹配中文,贪婪与非贪婪模式 Python爬虫教程-19-数据提取-正则表达式(re) 正则表达式 ...
- 一、CSS实现横列布局的方法总结
一.使用float实现横列布局的方法 如下面所示:DIV1和DIV2都可以选择向左或者向右浮动50%来实现展示在同一行 div1 div2 实现下面图片中布局的css样式如下: 分析: 1.第一行第一 ...
- Scrum团队开发
Scrum学习心得 什么是scrum Scrum是迭代式增量软件开发过程,通常用于敏捷软件开发.Scrum包括了一系列实践和预定义角色的过程骨架.Scrum中的主要角色包括同项目经理类似的Scrum主 ...
- 64位Navicat Premium-11.2.7(64bit)访问64位Oracle服务器
1 在windows 10 64位操作系统安装Navicat Premium-11.2.7(64bit). 2 在服务器安装64位的Oracle(win64_11gR2_database). 3 在h ...