js 怎么来写一个基类

2017-09-12 10:25:59 +08:00
 xiaomeimei
5320 次点击
所在节点    JavaScript
67 条回复
SuperMild
2017-09-12 13:21:16 +08:00
@wangyufeng 哈哈哈,对,就是乐趣,对于很多情况来说,原型链已经够用,甚至比 OO 更简单、清晰。
mcfog
2017-09-12 13:42:36 +08:00
都是图灵完备的语言,只有 JS 上不需要用的设计模式,不存在 JS 上实现不了的设计模式

楼主需要抛开其他所有 OO 语言的经验来看 JS,市面上基于原型链的语言几乎只有 JS 这一家,而几乎没有设计模式或者讨论 OO 的文章会基于 JS 来聊,太多的关于 JS 的 OO 的文章也都是生搬硬套其他语言的做法来误人子弟

回到楼主的比如,比如别的语言里你可能写 interface MyInterface {methodA(); methodB();} class MyClass implements MyInterface {.....} ,实际上在表达的是“给我 methodA 和 methodB 这两个方法,我帮你对接剩余的逻辑”,那么换到 JS 里,直接把接口能力作为依赖就行了

class EsClass {
constructor(methodA, methodB){}
...
}
sensui7
2017-09-12 14:31:56 +08:00
很讨厌楼主跟风用这个头像
qiuyk
2017-09-12 14:47:01 +08:00
@sensui7 我还以为你刚吐槽完 py 又来吐槽 js 哈哈哈

老实说以前写 C++写 C#,老是纠结于怎么定义好基类呀接口

自从写 js 以来好像就没想过这些事情
xiaomeimei
2017-09-12 15:53:33 +08:00
@mooncakejs 我试试吧。今天上午被禁了 1800s,回复太频繁了
xiaomeimei
2017-09-12 15:54:13 +08:00
@otakustay 面向接口是对的
xiaomeimei
2017-09-12 15:57:39 +08:00
@sensui7 哈哈~~~来咬我
xiaomeimei
2017-09-12 16:02:24 +08:00
@mcfog 是啊,不能生搬硬套,要根据语言特点来写
sensui7
2017-09-12 16:22:49 +08:00
@xiaomeimei 深刻诠释了抄袭者的嘴脸, 我无所谓, 这本来就是恶搞的头像, 对比两个图片, 看细节
yunying
2017-09-12 17:10:05 +08:00
js 为啥不能用设计模式?我天天写代码都在用
otakustay
2017-09-12 17:29:02 +08:00
@murmur 你说的这些都很有道理,但是却和你的问题无关
原型链 - JavaScript/ES - JS 引擎,这是 3 个层面的东西,你说的所有问题,都存在于语言和引擎之上,因此去推导原型链本身丑陋是不合适的,JS 不是唯一的基于原型的语言,比如 LUA 就要好看不少,R 和 Perl 加上原型相关的包后也不丑
lizhenda
2017-09-12 18:29:10 +08:00
```javascript
// 刚好我之前项目想用写了个,供参考
```
lizhenda
2017-09-12 18:30:22 +08:00
/**
* JavaScript Inheritance Class
*
* 实现了继承和定义对象,初始化自动调用 ctor() 构造函数,自带一个简单的 clone() 拷贝函数
* 每个 Class 都带有一个唯一 ID : _pid,每个 new 出来的对象也带一个唯一 ID : _uid (可以用于相同 Class 的不同对象)
*
* @author : zhenda.li
*/

/**
* @name ClassManager
*/
var ClassManager = {
pid: (0 | (Math.random() * 998)), // 每个 Class 的唯一 ID
uid: (0 | (Math.random() * 998)), // 每个 New 出来的对象唯一 ID

getPID: function () {
return this.pid++;
},

getUID: function () {
return this.uid++;
}
};

(function () {
var fnTest = /\b_super\b/;

this.Class = function () {
};

/**
* Create a new Class that inherits from this Class
* @static
* @param {object} prop
* @return {function}
*/
Class.extend = function (prop) {
var _super = this.prototype;
var prototype = Object.create(_super);
var desc = {writable: true, enumerable: false, configurable: true};

function Class() {
this._uid = ClassManager.getUID();
if (this.ctor) {
this.ctor.apply(this, arguments);
}
}

desc.value = ClassManager.getPID();
Object.defineProperty(prototype, '_pid', desc);

for (var name in prop) {
var isFunc = isFunction(prop[name]);
var override = isFunction(_super[name]);
var hasSuperCall = fnTest.test(prop[name]);

if (isFunc && override && hasSuperCall) {
desc.value = (function (name, fn) {
return function () {
var tmp = this._super;
this._super = _super[name];
var ret = fn.apply(this, arguments);
this._super = tmp;
return ret;
};
})(name, prop[name]);
Object.defineProperty(prototype, name, desc);
} else {
prototype[name] = prop[name];
}
}

Class.prototype = prototype;

desc.value = Class;
Object.defineProperty(Class.prototype, 'constructor', desc);

/**
* 快捷设置属性方法
* e.g : obj.attr({ x : 1, y : 2 });
*/
Class.prototype.attr = function (attrs) {
for (var key in attrs) {
if (!isUndefined(this[key]))
this[key] = attrs[key];
}
};

/**
* 每个对象自带拷贝方法
* @return Class
*/
Class.prototype.clone = function () {
var newObj = (this.constructor) ? new this.constructor : {};
for (var name in this) {
var copy = this[name];
if ((typeof copy) === "Class") {
newObj[name] = copy.clone();
} else {
newObj[name] = copy;
}
}
return newObj;
};

Class.extend = arguments.callee;

return Class;
};
})();
lizhenda
2017-09-12 18:32:32 +08:00
评论不能写 MD 么,至于用法,

var Test = Class.extend({

/**
* 构造函数, 初始化
*/
ctor: function () {
this.func();
},

func: function () {

}
});
lizhenda
2017-09-12 18:33:28 +08:00
当然,最好的办法是用 es6,直接上 class
azh7138m
2017-09-12 18:37:34 +08:00
工厂模式怎么就不能用了。。。。阿里云国际的控制台字段校验那个部分就是工厂模式啊
lijsh
2017-09-12 18:45:32 +08:00
littleshy
2017-09-12 18:51:46 +08:00
JS 是原型语言,不要用面向对象的思想去使用它。
chegde
2017-09-12 19:35:53 +08:00
TypeScript 大法好
aleung
2017-09-12 20:13:31 +08:00
不能说 js 不是 OO,js 是 prototype based OO

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/389990

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX