关于mixin的组织方式

来源:1-6 从入口开始

xjtumj

2018-06-15

其实用es6 class也可以用extend来拆分类实现,应该只是尤大的个人喜好问题吧,有些人不喜欢完全使用面向对象的写法

写回答

5回答

想上进的小前端

2020-07-08

没啥问题,都能实现,但是calss是一个语法糖,本质还是尤大使用的那一套

0
0

鸡肋2016

2019-09-23

提问者将代码混入的方法用es6尝试实验了,这样研究很赞!

但是我想知道提问者方法三,使用模拟多继承,实现完整类的mixin,

类Mix 混入多个mixin 后, mixin中如果在构造函数中有自身的属性和方法 Mix混入后是不是就会丢失

	class any{
		point(){
			console.log("i have point");
		}
	}

	class Rectangle extends any{

    // constructor
    constructor(height, width) {
    	super();
        this.height = height;
        this.width = width;
    }
    // Getter
    get area() {
        return this.calcArea()
    }
    // Method
    calcArea() {
        return this.height * this.width;
    }
}

function copyProperties(target, source) {
    const ownPropertyNames = Object.getOwnPropertyNames(source);
     
    ownPropertyNames
    .filter(key => !/^(prototype|name|constructor)$/.test(key))
    .forEach(key => {
    	
        const desc = Object.getOwnPropertyDescriptor(source, key);
        console.log(desc); 
        Object.defineProperty(target, key, desc)
    });
}

function mixin(...mixins) {
    class Mix {
    }
     
    for (const mixin of mixins) {
      copyProperties(Mix, mixin)
      copyProperties(Mix.prototype, mixin.prototype)
    }

    return Mix;
}


class Vue extends mixin(Rectangle) {
  // ...
}

let localVue = new Vue(3, 4);

console.dir(localVue.hasOwnProperty("height"));//false

 

0
0

xjtumj

提问者

2018-06-17

方法一,将拆分的方法和属性挂在prototype对象上
// main.js
import Init from 'instance/init';
import { mixin } from 'utils';
class Vue {
  // ...
}

mixin(Vue.prototype, Init);

export default Vue;


// init.js
export default {
  init() {
    console.log('init.');
  }
}

// utils.js
export function mixin(target, source) {
  return Object.assign(target, source);
}

// test.js
import Vue from 'main.js';
new Vue().init();

方法二,将拆分的方法和属性挂在实例对象上

// main.js
import Init from 'instance/init';
import { mixin } from 'utils';
class Vue {
  constructor() {
    mixin(this, Init);
  }
}
export default Vue;

方法三,使用模拟多继承,实现完整类的mixin:

// main.js
import Init from './instance/init';
import { mixin } from './utils';
class Vue extends mixin(Init) {
  // ...
}
export default Vue;

// utils.js
export function mixin(...mixins) {
    class Mix {
    }
    
    for (const mixin of mixins) {
      copyProperties(Mix, mixin)
      copyProperties(Mix.prototype, mixin.prototype)
    }
    
    return Mix;
}

function copyProperties(target, source) {
    const ownPropertyNames = Object.getOwnPropertyNames(source);
    
    ownPropertyNames
    .filter(key => !/^(prototype|name|constructor)$/.test(key))
    .forEach(key => {
        const desc = Object.getOwnPropertyDescriptor(source, key);
        
        Object.defineProperty(target, key, desc)
    });
}

// init.js
export default class {
    init() {
        console.log('init.');
    }
}


0
10
xjtumj
回复
ustbhuangyi
这个厉害了,那我的猜测确实是错误的,不过建议还是保留哈
2018-06-18
共10条回复

xjtumj

提问者

2018-06-17

```

markdown测试

```

0
0

ustbhuangyi

2018-06-16

那么问题来了,es6 的 class 如何把原型上的属性和方法拆分到不同的 JS 文件中呢?

0
5
xjtumj
回复
ustbhuangyi
ES6的Class只是一个语法糖,和ES5的mixin操作基本上是一样的,多了一种继承式的实现。我的实现方式详见讨论区(慕课追问回复无法格式化代码...)
2018-06-17
共5条回复

Vue.js 源码深入解析 深入理解Vue实现原理

全方位讲解 Vue.js 源码,进阶高级工程师

4984 学习 · 1037 问题

查看课程