javascript模拟类的最佳实践
1:怎样模拟一个类
在sencha touch2 系列里面定义一个类和new出这个类的对象
Ext.define(
"Animal", {
config: {
name: null
},
constructor: function(config) {
this.initConfig(config);
},
speak: function() {
console.log('说点什么');
}
}
) var my=Ext.create("Animal",{name:"bb"})
my.speak();
上面代码里面constructor在create的时候会自己主动调用。然后初始化config对象配置的属性。
constructor全然就像面对象里面的构造函数……
以下我模拟一下
// 在sencha中new一个对象传了两个參数Ext.create("Animal",{name:"bb"})
// 这里就不模拟sencha的命名空间了,所以生成该类的对象的时候传一个配置对象就可以
// 把命名空间(mss)和命名单独提取出来,new mss.define({});
var mss = {} //建立一个命名空间
mss.define = function(config) {
if(typeof config !== 'object') {
console.log('參数错误');
return;
}
var interface = function() { //当new 该define返回的函数。会自己主动运行atrr和init
this.attr && this.attr();
this.init && this.init.apply(this, arguments);
}
for(var i in config) {
config.hasOwnProperty(i) &&(interface.prototype[i] = config[i]);
}
return interface;
}
var Car = mss.define({
attr: function() {
this.type = '汽车';
},
init: function() {
console.log(this.type);
},
speank: function() {
console.log('我是' + this.type);
}
});
var car1 = new Car();
car1.speank();
输出
汽车
我是汽车
[Finished in 0.1s]
这样就模拟成了:define一个类。然后new出来调用其方法;
2:怎样在此基础上继承一个类
首先看看sencha touch2系列的继承
Ext.define(
"Person", {
extend: "Animal",
speak: function() {
console.log('我是人');
}
}
)
加多一个属性extend搞定。
以下在mss.define模拟一下
// 在sencha中new一个对象传了两个參数Ext.create("Animal",{name:"bb"})
// 这里就不模拟sencha的命名空间了。所以生成该类的对象的时候传一个配置对象就可以
// 把命名空间(mss)和命名单独提取出来,new mss.define({});
var _mss = {} //建立一个命名空间
_mss.Define = function(parClass, curConfig) {
// 若sup 是个object,表示这是一个新类
// 若sup 是个function,表示这是一个继承
if(typeof parClass === 'object') {
curConfig = parClass;
parClass = function() {};
}
// 定义返回类
// 当new 该define返回的函数。会自己主动运行atrr和init
var interface = function() {
this.attr && this.attr();
this.init && this.init.apply(this, arguments);
}
// 返回类继承 parClass
interface.prototype = new parClass();
// 为返回类包括的两个初始化函数定义基础方法
// 获得继承的init方法 和attr方法
// 假设parClass存在init方法,那么nterface.prototype.init
// 和new parClass().init相等
var parInit = interface.prototype.init || function() {};
var curInit = curConfig.init || function() {};
var parAttr = interface.prototype.attr || function() {};
var curAttr = curConfig.attr || function() {};
// 为返回类原型初始化当前属性,这里注意可能被后面的方法重写
for(var i in curConfig) {
curConfig.hasOwnProperty(i) && (interface.prototype[i] = curConfig[i]);
}
// 假设当前返回类已经继承了init,重写该方法
if(arguments.length && arguments[0].prototype && arguments[0].prototype.init === parInit) {
interface.prototype.init = function() {
var scope = this;
var args = [function() {
parInit.apply(scope, arguments);
}];
var slice = [].slice;
curInit.apply(scope, args.concat(slice.call(arguments)));
}
}
// 假设当前返回类已经继承了attr,重写attr 或者是首次构造改方法(新类)
interface.prototype.attr = function() {
parAttr.call(this);
curAttr.call(this);
}
// 继承父类的成员属性
for(var i in parClass) {
parClass.hasOwnProperty(i) && (interface[i] = parClass[i]);
}
return interface;
}
var Car = _mss.Define({
attr: function() {
this.type = '汽车';
},
init: function() {
console.log(this.type);
},
speank: function() {
console.log('我是' + this.type);
}
});
var car1 = _mss.Define(Car, {
})
new car1().speank();
输出
汽车
我是汽车
[Finished in 0.1s]
对于call实现继承
interface.prototype.attr = function() {
parAttr.call(this);
curAttr.call(this);
}
在Chorome控制台打印这段代码就能够解释一下这段代码了
var _Attr = function() {
this.a = 1;
}
var B = function() {
this.attr();
};
B.prototype.attr = function(){_Attr.call(this);}
console.log(new B());
VM665:9 B {a: 1}a: 1__proto__: Battr: (){_Attr.call(this);}constructor: () {__proto__: Object
javascript模拟类的最佳实践的更多相关文章
- [原创]Javascript模拟“类”的综合实现方式以及部分细节【截至ES6】
[原创]Javascript模拟“类”的综合实现方式以及部分细节[截至ES6] 前言 最近几个旧项目里使用的图片编辑插件出现Bug, 经Review 后确定需要在其内外均做些改动,但是头疼的发现部 ...
- JavaScript best practices JS最佳实践
JavaScript best practices JS最佳实践 0 简介 最佳实践起初比较棘手,但最终会让你发现这是非常明智之举. 1.合理命名方法及变量名,简洁且可读 var someItem = ...
- JavaScript 定义类的最佳写法——完整支持面向对象(封装、继承、多态),兼容所有浏览器,支持用JSDuck生成文档
作者: zyl910 [TOC] 一.缘由 由于在ES6之前,JavaScript中没有定义类(class)语法.导致大家用各种五花八门的办法来定义类,代码风格不统一.而且对于模拟面向对象的三大支柱& ...
- [笔记]《JavaScript高级程序设计》- 最佳实践
一.可维护性 1 什么是可维护的代码 可理解性--其他人可以接受代码并理解它的意图和一般途径,而无需原开发人员的完整解释. 直观性--代码中的东西一看就能明白,不管其操作过程多么复杂. 可适应性--代 ...
- JavaScript的技巧和最佳实践
JavaScript是一个绝冠全球的编程语言,可用于Web开发.移动应用开发(PhoneGap.Appcelerator).服务器端开发 (Node.js和Wakanda)等等.JavaScript还 ...
- JavaScript 最佳实践
这个文档是基于JavaScript社区众多开发者的意见和经验,在开发JavaScript代码上的最佳实践和首选的方案的明细表.因为这是一个推荐的表而非原则性的方案,经验丰富的开发者可能对下面的表达会有 ...
- JavaScript Web 应用最佳实践分析
[编者按]本文作者为 Mathias Schäfer,旨在回顾在客户端大量使用JavaScript 的最佳 Web应用实践.文章系国内 ITOM 管理平台 OneAPM 编译呈现. 对笔者来说,Jav ...
- Javascript定义类(class)的三种方法
将近20年前,Javascript诞生的时候,只是一种简单的网页脚本语言.如果你忘了填写用户名,它就跳出一个警告. 如今,它变得几乎无所不能,从前端到后端,有着各种匪夷所思的用途.程序员用它完成越来越 ...
- [转]Javascript定义类的三种方法
作者: 阮一峰 原文地址:http://www.ruanyifeng.com/blog/2012/07/three_ways_to_define_a_javascript_class.html 将近2 ...
随机推荐
- 织梦(dedecms)循环调用多级子栏目如二级栏目下三级栏目
本文是关于织梦DedeCMS调用多级子栏目的,拿来分享下. 后台已经建好栏目,对于产品展示栏 栏目导航如下图所示: 复制代码 代码如下: {dede:channelartlist cacheid=' ...
- ProGuard常见问题及解决套路
ProGuard是一个压缩.优化和混淆Java字节码的工具,非常好用.本篇文章总结一下许多人在使用ProGuard时经常遇到的问题. 我把在使用ProGuard时经常遇到的问题分为两类,分别是导致构建 ...
- 紫书 习题8-10 UVa 1614 (贪心+结论)
这道题我苦思冥想了一个小时, 想用背包来揍sum/2, 然后发现数据太大, 空间存不下. 然后我最后还是去看了别人的博客, 发现竟然有个神奇的结论-- 幸好我没再钻研, 感觉这个结论我肯定是想不到的- ...
- 12个Unity5中优化VR 应用的技巧
本文章由cartzhang编写,转载请注明出处. 所有权利保留. 文章链接:http://blog.csdn.net/cartzhang/article/details/50176429 作者:car ...
- linux查找某个命令属于哪个rpm包
我们拿pip命令来举例 方法一: 确认命令的路径 # which pip /usr/bin/pip 用yum命令查找pip属于哪个rpm包 # yum whatprovides /usr/b ...
- 洛谷 P2818 天使的起誓
P2818 天使的起誓 题目描述 Tenshi非常幸运地被选为掌管智慧之匙的天使.在正式任职之前,她必须和其他新当选的天使一样要宣誓.宣誓仪式是每位天使各自表述自己的使命,他们的发言稿放在n个呈圆形排 ...
- Linux线程相互排斥量--进程共享属性
多线程中.在相互排斥量和 读写锁的 属性中.都有一个叫 进程共享属性 . 对于相互排斥量,查询和设置这个属性的方法为: pthread_mutexattr_getpshared pthread_mut ...
- bzoj1433: [ZJOI2009]假期的宿舍(最大二分图匹配)
1433: [ZJOI2009]假期的宿舍 题目:传送门 题解: 这题有点水 跑个二分图匹配就完事了(注意在校生不是一定都互相认识) 代码: #include<cstdio> #inclu ...
- 将一个文件夹纳入library或者移除remove
https://support.microsoft.com/en-us/help/4026298/windows-show-libraries-in-file-explorer To show lib ...
- Struts2 | struts.xml文件中使用method属性和通配符简化action标签和Action处理类的编写
转自:https://www.jianshu.com/p/310e89ee762d 在Struts2框架中,我们知道基本的Action标签只能实现一个url请求对应一个Action处理类.那么我们如果 ...