采纳答案成功!
向帮助你的同学说点啥吧!感谢那些助人为乐的人
其实用es6 class也可以用extend来拆分类实现,应该只是尤大的个人喜好问题吧,有些人不喜欢完全使用面向对象的写法
没啥问题,都能实现,但是calss是一个语法糖,本质还是尤大使用的那一套
提问者将代码混入的方法用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
方法一,将拆分的方法和属性挂在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.'); } }
额,你这基本上就是把 function 换成了 class,还是给原型上去扩展了方法,我认为和 Vue 目前的实现并没有什么本质区别。
另外 Vue 并不是完全不会用 class,比如 VNode 就是 class 的实现,所以我觉得你的猜测尤大的喜好问题站不住脚。
本来es6的class就是个语法糖,没有什么本质的区别,也有可能是vnode是后来写的代码,vue初始版本是很早的,当时es6还没有出来,后来觉得这里改class没有什么必要,就保留了这里。 但是视频中说是用es6不好实现,这个就不对了,现在的情况下应当提倡使用es6的语法,虽然是个语法糖,但也能更加统一和拥抱标准
```
markdown测试
那么问题来了,es6 的 class 如何把原型上的属性和方法拆分到不同的 JS 文件中呢?
一样的呀,mixin和继承基本是一个概念,把类拆分到不同的文件中,使用类的继承是一样的效果
而且就算不用继承,prototype的属性方法全部mixin到this上也未尝不可,本身就是单例
可否举个例子?
登录后可查看更多问答,登录/注册
全方位讲解 Vue.js 源码,进阶高级工程师
3.0k 4
1.5k 20
1.3k 14
1.2k 12
2.2k 12