JS类的包装及贯彻代码

作者: 前端技术  发布:2019-09-06

1. 定义js类
js而不是一种面向对向的言语, 未有提供对类的支撑, 由此大家无法像在价值观的言语里那么 用class来定义类, 但大家得以运用js的闭包封装机制来达成js类, 大家来封装二个简的Shape类.

复制代码 代码如下:

function ShapeBase() {
this.show = function()
{
alert("ShapeBase show");
};
this.init = function(){
alert("ShapeBase init");
};
}

本条类里定义了八个艺术:show和init, 须要注意的是这里运用了this来声称, 实际不是var, 因为用var是用来定义私有方法的.
别的, 大家还足以用prototype属性来定义Shape的方法.

复制代码 代码如下:

ShapeBase.prototype.show=function()
{
alert("ShapeBase show");
}
ShapeBase.prototype.init=function()
{
alert("ShapeBase init");
}

下面这种写法看起来不太直观,我们得以将富有的主意写在一同.

复制代码 代码如下:

ShapeBase.prototype={
show:function()
{
alert("ShapeBase show");
},
init:function() {
alert("ShapeBase init");
}
};

明天, 类是写好了, 让我们写个js来测量检验下, 看看结果是或不是跟大家想像的同样啊?

复制代码 代码如下:

function test(src){
var s=new ShapeBase();
s.init();
s.show();
}

总的来看了吗, 其调用格局和C#长久以来, 而结果也如作者辈所料.
到方今甘休, 大家学会了怎么样创制js的类了, 但还只是实例方法,假设完结跟C#中的静态方法要咋办吧?
其实, 实现js的静态方法很轻便, 看上边怎么样兑现:

复制代码 代码如下:

//静态方法
ShapeBase.StaticDraw = function()
{
alert("method draw is static");
}

2. 落到实处JS类抽象和承继 同等, js中也不支持类承袭机制,但大家能够通过将父类prototype中的成员方法复制到子类的prototype中来达成.
和类的存在延续一样,JavaScript也从没别的机制用来扶助抽象类.但使用JavaScript语言本人的性质.能够完结和睦的画个饼来解除饥饿类.
率先来拜会js中的虚方法, 在价值观语言中虚方法是要先定义的, 而包蕴虚方法的类就是抽象类,不可能被实例化,而在JavaScript中,虚方法就能够看作该类中未有概念的点子,但一度由此this指针使用了.
和价值观面向对象差别的是,这里虚方法不需通过证明,而平昔利用了, 何况类也得以被实例化.
先定义object的extend方法, 三个为静态方法,二个为实例方法, 那四个点子用于落到实处延续的prototype复制

复制代码 代码如下:

Object.extend = function(destination, source) {
for (property in source) {
destination[property] = source[property];
}
return destination;
}
Object.prototype.extend = function(object) {
return Object.extend.apply(this, [this, object]);
}

接下去我们贯彻三个持续类Rect, 这里先用一种简易的方式来兑现。

复制代码 代码如下:

function Rect() {
}
Rect.prototype = ShapeBase.prototype; //只这一句就行了
//扩展新的章程
Rect.prototype.add=function() {
alert("Rect add");
}

这种办法不能够用来重写,如若退换了show方法, ShapeBase的show也会针对同一函数大概是出于prototype赋值只是简短的变动指向地址.
借使上边也定义了:
Rect.prototype.show=function() {
alert("Rect show");
}
那么施行结果如下:
function test(){
var s=new ShapeBase();
s.show(); //结果:Rect show
var r=new Rect();
r.show(); //结果:Rect show
r.add();
}
咱俩再使用object.extend达成一连, 并达成三个oninit虚方法, 修改ShapeBase如下:

复制代码 代码如下:

ShapeBase.prototype={
show:function()
{
alert("ShapeBase show");
},
initialize:function () {
this.oninit();
}
};

实现Rect类继承.

复制代码 代码如下:

Rect.prototype=(new ShapeBase).extend({
//增加新的秘技
add:function() {
alert("Rect add");
},
//使用这种办法能够重写show方法
show:function() {
alert("Rect show");
},
//完成虚方法
oninit:function() {
alert("Rect oninit");
}
})

今昔大家的类写好了, 测验下看看:

复制代码 代码如下:

function test(src){
ShapeBase.StaticDraw();
var s=new ShapeBase();
s.show(); //alert("ShapeBase show")
var r=new Rect();
r.show(); //alert("Rect show")
r.add();
r.initialize(); //alert("Rect oninit")
}

除此以外,在网络看看一篇用非常的对象来成立类,代码如下:

复制代码 代码如下:

//
//对象属性复制方法,非常多库都有落到实处,如PrototypeJS里面包车型客车extend和Ext里面包车型客车Ext.apply
//
function extend(des, src) {
if (!des)
des = {};
if (src) {
for (var i in src) {
des[i] = src[i];
}
}
return des;
}
var CC = {}; //全局变量
//
//create 用于创设类
//
CC.create = function(superclass, constructor){
var clazz = (function() {
this.initialize.apply(this, arguments);
});
//假诺无参数,间接再次回到类.
if(arguments.length == 0)
return clazz;
//借使无父类,此时constructor应为一个纯对象,直接复制属性再次回到.
if(!superclass){
extend(clazz.prototype, constructor);
return clazz;
}
var absObj = clazz.prototype,
sprPropty = superclass.prototype;
if(sprPropty){
//用于访谈父类方法
clazz.superclass = sprPropty;
extend(absObj, sprPropty);
//调用属性构造函数成立属性,这么些是完成关键.
extend(absObj, constructor(sprPropty));
// 子类实例间接通过obj.superclass访谈父类属性,
// 若是不想产生过多援用,也可把这句注释掉,因为比较多时候是没供给的.
absObj.superclass = sprPropty;
//
clazz.constructor = constructor;
}
return clazz;
}
//
//创造二个动物类
//
var Animal = CC.create(null, {
//属性
footprint : '- - - - - - =',
//类伊始化方法,必得的,当用 new 生成二个类时该方法自动被调用,参见上定义.
initialize : function(options){
extend(this, options);
alert('Animal initialize method is called.');
},
eat : function(){
alert('Animal eat method is called.');
},
move : function(){
alert('I am moving like this '+ this.footprint +' .');
}
});
//
//创造四个Duke类
//
var Duke = CC.create(Animal, function(superclass){
//在那足以定义一些类全局静态数据,该类各类实例都共享这一个数据.
//总括实例个类,富含派生类实例.
var static_instance_counter = 0;
function classUtilityFuncHere(){ }
//重返类具体属性.
return {
//重写初阶化方法
//@override
initialize : function(options) {
alert('Initializing Duke class..');
//调用父类发轫化,这种方式比相似另外库的要简洁点吧,能够任由父类是什么.
superclass.initialize.call(this, options);
//做一些子类喜欢做的事.
alert('Duke initialize method is called.');
//读取或修改类静态属性
static_instance_counter++;
},
//重写move方法,增添Duke自身的位移格局.
move : function(){
this.footprint = this.footprint + 'zzzzzzzz';
superclass.move.call(this);
},
//重写eat方法,注意,里面不调用父类方法,即父类eat被遮蔽了.
eat : function(){
alert('Duke is eating..');
},
//新添多少个say方法,展现当前已经开首化的Duke类实例数量.
say : function(){
alert('the number of Duke instances is '+static_instance_counter);
}
};
});
var DukeChild = CC.create(Duke, function(superclass){
return {
move : function(){
this.footprint = this.footprint + '++++++++++++=';
superclass.move.call(this);
},
say : function(){
alert(this.msg || '');
}
};
});
(function test() {
var animal = new Animal();
animal.eat();
animal.move();
var dukeA = new Duke();
dukeA.eat();
dukeA.move();
dukeA.say();
var dukeB = new Duke();
dukeB.eat();
dukeB.move();
dukeB.say();
var dukeC = new DukeChild({msg : 'I am a child of duke.'});
dukeC.move();
dukeC.say();
})();

. 定义js类 js并非一种面向对向的言语, 未有提供对类的扶助, 由此大家不可能像在观念的言语里那么 用class来定义类, 但大家能够运用js的闭...

本文由今晚开什么码发布于前端技术,转载请注明出处:JS类的包装及贯彻代码

关键词: