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 ...
随机推荐
- Sublime Text编辑器配置Python解释器简易教程
前天在微信上遇到一个小伙伴问我一个关于Sublime text配置Python解释器的问题,可能是初学者,对这方面还不是很懂,想使用快捷键但是徒劳一场,因为缺少Python解释器,直接按下快捷键Ctr ...
- 【BZOJ2006】【NOI2010】超级钢琴
题意: Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符 ...
- 【Henu ACM Round#24 B】Gargari and Bishops
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 如果写过n皇后问题. 肯定都知道 某个点(i,j)和它在同一条对角线上的点分别是i+j的值和i-j的值相同的点. 然后会发现选择的两 ...
- Tarjan 割点割边【模板】
#include <algorithm> #include <cstring> #include <cstdio> using namespace std; +); ...
- 洛谷 P2049 魔术棋子
P2049 魔术棋子 题目描述 在一个M*N的魔术棋盘中,每个格子中均有一个整数,当棋子走进这个格子中,则此棋子上的数会被乘以此格子中的数.一个棋子从左上角走到右下角,只能向右或向下行动,请问此棋子走 ...
- VS2015--win32project配置的一些想法之cmake
近期两天都在配置一个win32项目.为了实现跨平台,写底层代码的人仅仅build了安卓和ios的工程,没有build win32项目. 因为对一些库不是非常了解.配置起来非常困难,心力交瘁. 为了实现 ...
- LightOJ - 1038 Race to 1 Again 递推+期望
题目大意:给出一个数,要求你按一定的规则将这个数变成1 规则例如以下,如果该数为D,要求你在[1,D]之间选出D的因子.用D除上这个因子,然后继续按该规则运算.直到该数变成1 问变成1的期望步数是多少 ...
- 关于functioncharts饼状图篇
关于functioncharts饼状图(仅限饼状图) TODO: 1.饼状图没有数据情况下,显示:no data to display 2,解决的方法:自己定义处理.显示图像或其他内容
- 安装xcode6 beta 后调试出现Unable to boot the iOS Simulator以及编译苹果官方Swift的demo报错failed with exit code 1的解决的方法
苹果昨天公布新语言Swift(雨燕),须要安装xcode6 以及mac os 系统为10.9以上. (xcode6 beta 可在官方下载.须要登录开发人员账号:mac os 系统直接更新就可以.在此 ...
- xml布局内容总结(四)--Android
(1)对于xml编写界面较复杂的情况下,使用include会使得编写和查看更清楚 <LinearLayout android:layout_width="mat ...