js 类工厂

js中的类工厂就是因为js中一直没有真正的类。创建类工厂是为了模拟类,类工厂的主要部分就是prototype的扩展和返回一个基本的用来new的函数

prototype扩展

首先是prototype的扩展,可以用一个简单的for...in...循环来实现。

for(var item in from){
if(from.hasOwnProperty(item)){
target[item] = from[item];
}
}

但是自从有getOwnPropertyDescriptor后,我们就有了一个更好的方法来拷贝prototype中的属性。通过getOwnPropertyDescriptor函数,可以将prototype的属性中[[writable]],[[enumerable]]等等属性都取到,然后通过defineProperty方法将其设置到新的prototype中。

不过要考虑兼容老版本的浏览器,于是要对浏览器是否支持getOwnPropertyDescriptor作一个判断,最后的函数如下:


function mixpro(target,from){
if(Object.getOwnPropertyDescriptor){
Object.keys(from).forEach(function(property){
Object.defineProperty(target, property, Object.getOwnPropertyDescriptor(from, property));
})
}else{
for(var item in from){
if(from.hasOwnProperty(item)){
target[item] = from[item];
}
}
}
};


主要定义的函数extend

在这里需要定义一个函数,用于返回一个基本的函数,用于后面的实例化。由于考虑到后面的继承父类,我们要引入一个参数,在需要时禁止init的运行,代码如下:


var Base = function(){
if(!is_init && this.init){
var old_super = this.super;
this.super = _super;
this.init.apply(this,arguments);
this.super = old_super;
}
};

然后就是其中的super问题了,即在运行init的时候,让其可以调用到父类的属性(通过this.super.propertyName),于是就要得到对父对象prototype的引用。

var _super = this.prototype;

然后就是函数中将父元素的方法继承下来,然后在混入自己定义的方法:

is_init = true;
proto = new this();
is_init = false;
mixpro(proto, definition);

最后再进行一系列对象引用位置的调整,得到最后函数:


var extend = Class.extend = function(definition){
if(typeof definition !== ‘object‘){
return;

}
var _super = this.prototype;
is_init = true;
proto = new this();
is_init = false;
mixpro(proto, definition);
var Base = function(){
if(!is_init && this.init){
var old_super = this.super;
this.super = _super;
this.init.apply(this,arguments);
this.super = old_super;
}
};
Base.prototype = proto;
Base.prototype.constructor = Base;
Base.extend = arguments.callee;
return Base;
};

完整的代码:


(function(global){
var Class,is_init = false,proto;
Class = function(){};
function mixpro(target,from){
if(Object.getOwnPropertyDescriptor){
Object.keys(from).forEach(function(property){
Object.defineProperty(target, property, Object.getOwnPropertyDescriptor(from, property));
})
}else{
for(var item in from){
if(from.hasOwnProperty(item)){
target[item] = from[item];
}
}
}
};
var extend = Class.extend = function(definition){
if(typeof definition !== ‘object‘){
return;
}
var _super = this.prototype;
is_init = true;
proto = new this();
is_init = false;
mixpro(proto, definition);
var Base = function(){
if(!is_init && this.init){
var old_super = this.super;
this.super = _super;
this.init.apply(this,arguments);
this.super = old_super;
}
};
Base.prototype = proto;
Base.prototype.constructor = Base;
Base.extend = arguments.callee;
return Base;
};

global.Class = Class;
})(window);

<方式继承

在司徒正美的书中有看到用<号来实现继承,这个原理就是<号出现会对两边求值,如果非基本变量的话,会先尝试调用其valueOf函数,若不能得到基本变量,就会调用toString,如果我们改写valueOf函数,就可以在内部实现继承了

至于如何实现,啊我懒得写了。。。。。

时间: 2024-10-13 08:39:13

js 类工厂的相关文章

JS类定义方式

// 方法1 对象直接量 var obj1 = { v1 : "", get_v1 : function() { return this.v1; }, set_v1 : function(v) { this.v1 = v; } }; obj1.set_v1('hello1'); alert(obj1.get_v1()); // 方法2 定义函数对象 var Obj = function() { var v1 = ""; this.get_v1 = function(

第六章:类工厂

类与继承在javascript的出现,说明javascript已经达到大规模开发的门槛了,在之前是ECMAScript4,就试图引入类,模块等东西,但由于过分引入太多的特性,搞得javascript乌烟瘴气,导致被否决.不过只是把类延时到ES6.到目前为止,javascript还没有正真意义上的类.不过我们可以模拟类,曾近一段时间,类工厂是框架的标配,本章会介绍各种类实现,方便大家在自己的框架中或选择时自己喜欢的那一类风格. 1.javascript对类的支持 在其它语言中 ,类的实例都要通过构

C++ &nbsp; 类工厂实现动态对象创建

看了MFC中的动态创建对象后,感觉动态创建对象算是一种技术吧,理论上说算是一种设计模式.其实创建的原理很明了,把对象的类别名称和其构造函数用容器记录下来,在需要的时候给出创建类别查找容器即可创建对象.当然这里我们需要自定义一个全局的函数指针用来指向类别的构造函数.在这里我们使用类工厂模式,在泪工厂中我们定义一个通用构造函数,将函数指针指向它.下面是参考一位网友思路来整理和摸索的代码: //通用的函数指针 typedef  void *(*CREATE_FUNC)(); //创建类的工厂类 cla

自定义类工厂方法

1.自定义工厂方法 什么是工厂方法(快速创建方法) 类工厂方法是一种用于分配.初始化实例并返回一个它自己的实例的类方法.类工厂方法很方便,因为它们允许您只使用一个步骤(而不是两个步骤)就能创建对象. 例如new 自定义类工厂方法的规范 (1)一定是+号开头 (2)返回值一般是instancetype类型 (3)方法名称以类名开头,首字母小写 示例 + (id)person; + (id)person { return [[Person alloc]init]; } + (id)personWit

[备忘]检索 COM 类工厂中 CLSID 为 {91493441-5A91-11CF-8700-00AA0060263B} 的组件时失败解决方法

检索 COM 类工厂中 CLSID 为 {91493441-5A91-11CF-8700-00AA0060263B} 的组件时失败,原因是出现以下错误: 80070005 在CSDN上总是有网友问这个问题,自己也遇到过,因些写出来供参考: 症状: oWordApplic = New Word.Application 当程序运行到这句时出现下面的错误: 检索 COM 类工厂中 CLSID 为 {91493441-5A91-11CF-8700-00AA0060263B} 的组件时失败,原因是出现以下

两种简单实现菜单高亮显示的JS类(转载)

两种简单实现菜单高亮显示的JS类 近期在写一个博客管理后台的前端,涉及在同一页面两种高亮显示当前菜单的需求.记得当年写静态页时,为了实现高亮都是在每个页面加不同的样式,呵.高亮显示我觉得对于web前端来说,是比较常用到的效果,正好此次又要用到,特地整理出我所写的两种高亮类. 其实思路很简单,第一种方法是通过遍历链接组的href值,通过indexOf判断href值是否被包含在浏览器当前url值中.此方法有一定局限,比如对于iframe内的菜单是不能这样判断的; 第二种方法适用范围更广一样,实现思路

JS类的封装及实现代码

js并不是一种面向对向的语言, 没有提供对类的支持, 因此我们不能像在传统的语言里那样 用class来定义类, 但我们可以利用js的闭包封装机制来实现js类, 我们来封装一个简的Shape类. 1. 定义js类 js并不是一种面向对向的语言, 没有提供对类的支持, 因此我们不能像在传统的语言里那样 用class来定义类, 但我们可以利用js的闭包封装机制来实现js类, 我们来封装一个简的Shape类. 代码如下: function ShapeBase() { this.show = functi

检索 COM 类工厂中 CLSID 为 {00024500-0000-0000-C000-000000000046} 的组件时失 败,原因是出现以下错误:80040154

检索 COM 类工厂中 CLSID 为 {00024500-0000-0000-C000-000000000046} 的组件时失 败,原因是出现以下错误: 80040154 折腾了N个小时的问题,最终是通过这个ID去搜索未报错的机器的注册表,导出,再导入到报错的机器上,问题得到解决.原来是开发文档提示注册的ocx有误. 其他:只有服务器上安装了office序列才可以调用office的东西 其他问题相关: http://zhidao.baidu.com/question/532301026.htm

检索 COM 类工厂中 CLSID 为 {{10020200-E260-11CF-AE68-00AA004A34D5}} 的组件时失败解决办法

检索 COM 类工厂中 CLSID 为 {10020200-E260-11CF-AE68-00AA004A34D5} 的组件时失败,解决方法如下: 第一步:首先将msvcr71.dll,  SQLDMO.DLL, Resources/2052/sqldmo.rll,Resources/1033/sqldmo.rll 拷贝到C:/Program Files/Microsoft SQL Server/80/Tools/Binn目录. 下载SQLDMO文件 第二步:打开开始,在运行中输入 regsvr