JavaScript的"类"
1. 基本创建“类”方式
var Class = function(){
var klass = function(){
this.init.apply(this, arguments);
};
klass.prototype.init = function(){};
return klass;
}; var Person = new Class();
Person.prototype.init = function(){
// 基于Person 的实例做初始化
}; Person.find = function(id){ /*...*/ };
Person.prototype.breath = function(){ /*...*/ };
Person.fn = Person.prototype;
Person.fn.run = function(){ /*...*/ }; // 用法
var person = new Person();
person.find(1);
person.breath();
person.run();
2. 分辨类的静态属性和实例的属性
var Class = function() {
var klass = function() {
this.init.apply(this, arguments);
};
klass.prototype.init = function() {};
//定义 prototype 的别名
klass.fn = klass.prototype;
// 定义类的别名
klass.fn.parent = klass;
// 给类添加属性
klass.extend = function(obj) {
var extended = obj.extended;
for (var i in obj) {
klass[i] = obj[i];
}
if (extended) extended(klass);
};
// 给实例添加属性
klass.include = function(obj) {
var included = obj.included;
for (var i in obj) {
klass.fn[i] = obj[i];
}
if (included) included(klass);
};
return klass;
}; var Person = new Class();
// 添加静态属性
Person.extend({
find: function(id) { /* ... */ },
exists: function(id) { /* ... */ }
});
//添加实例属性
Person.include({
save: function(id) { /* ... */ },
destroy: function(id) { /* ... */ }
}); var person = new Person();
person.save();
在类之间共享通用的属性
var ORMModule = {
save: function(){
// 共享的函数
}
};
var Person = new Class();
var Asset = new Class(); Person.include(ORMModule);
Asset.include(ORMModule);
JavaScript 是基于原型的编程语言,原型用来区别类和实例,这里提到一个概念:原型对象(prototypical object)。原型是一个“模板”对象,它上面的属性被用做初始化一个新对象。任何对象都可以作为另一个对象的原型对象,以此来共享属性。
当读取一个对象的属性时,JavaScript 首先会在本地对象中查找这个属性,如果没有找到,JavaScript 开始在对象的原型中查找,若还未找到还会继续查找原型的原型,直到查找到Object.prototype。如果找到这个属性,则返回这个值,否则返回undefined。
为了让子类继承父类的属性,首先需要定义一个构造函数。然后需要将父类的新实例赋值给构造函数的原型。
var Animal = function(){};
Animal.prototype.breath = function(){
console.log('breath');
}; var Dog = function(){}; // Dog 继承了Animal
Dog.prototype = new Animal();
Dog.prototype.wag = function(){
console.log('wag tail');
}; var dog = new Dog();
dog.wag();
dog.breath(); // 继承的属性
3. 添加继承,通过传入一个可选的父类来创建新类
var Class = function(parent) {
var klass = function() {
this.init.apply(this, arguments);
}; // 改变klass 的原型 只有实例的属性才会被继承,而非类的属性
if (parent) {
var subclass = function() { };
subclass.prototype = parent.prototype;
klass.prototype = new subclass;
}; klass.prototype.init = function() {};
//定义 prototype 的别名
klass.fn = klass.prototype;
// 定义类的别名
klass.fn.parent = klass;
klass._super = klass.__proto__; // 给类添加属性
klass.extend = function(obj) {
var extended = obj.extended;
for (var i in obj) {
klass[i] = obj[i];
}
if (extended) extended(klass);
};
// 给实例添加属性
klass.include = function(obj) {
var included = obj.included;
for (var i in obj) {
klass.fn[i] = obj[i];
}
if (included) included(klass);
};
return klass;
}; var Animal = new Class();
Animal.include({
breath: function(){
console.log('breath');
}
});
var Cat = new Class(Animal);
var tommy = new Cat();
tommy.breath();
apply() 函数有两个参数:第1 个参数是上下文对象,第2 个参数是参数组成的数组。如果上下文对象是null,则使用全局对象代替。
call() 函数的行为和apply() 函数类似,只是使用方法不一样。call() 的第1 个参数是上下文对象,后续是实际传入的参数序列。
functionName.apply(this, [1, 2, 3]);
functionName.call(this, 1, 2, 3);
使用apply() 和call() 来更改上下文对象
//为了访问原始上下文对象,可以将this 的值存入一个局部变量中。
var clicky = {
wasClicked: function(){ },
addListeners: function(){
var self = this;
$('.clicky').click(function(){
self.wasClicked();
});
}
};
clicky.addListeners(); //可以使用apply 来将这段代码变得更干净一些,通过将回调包装在另外一个匿名函数中,来保持原始的上下文
var proxy = function(func, thisObject){
return function(){
return func.apply(thisObject, arguments);
};
}; var clicky = {
wasClicked: function(){ },
addListeners: function(){
var self = this;
$('.clicky').click(proxy(this.wasClicked, this));
}
};
clicky.addListeners();
4. 控制“类”的作用域 在类和实例中都添加proxy函数
var Class = function(parent){
var klass = function(){
this.init.apply(this,arguments);
}
//继承
if (parent) {
var subclass = function() { };
subclass.prototype = parent.prototype;
klass.prototype = new subclass();
} klass.prototype.init = function(){};
klass.fn = klass.prototype;
klass.fn.parent = klass;
klass._super = klass.__proto__; //类 静态属性
klass.extend = function(obj){
var extended = obj.extended;
for(var i in obj){
klass[i] = obj[i];
}
if(extended) extended(klass);
}
//类 实例属性
klass.include = function(obj){
var included = obj.included;
for(var i in obj){
klass.fn[i] = obj[i];
}
if(included) included(klass);
}
//类 作用域
klass.proxy = function(func){
var self = this;
return(function(){
return func.apply(self, arguments);
});
}
klass.fn.proxy = klass.proxy; return klass;
} var Button = new Class();
Button.include({
init: function(element){
this.element = jQuery(element);
// 代理了这个click 函数
this.element.click(this.proxy(this.click));
},
click: function(){ }
});
JavaScript的"类"的更多相关文章
- 详解javascript的类
前言 生活有度,人生添寿. 原文地址:详解javascript的类 博主博客地址:Damonare的个人博客 Javascript从当初的一个"弹窗语言",一步步发展成为现在前后端 ...
- Javascript定义类(class)的三种方法
将近20年前,Javascript诞生的时候,只是一种简单的网页脚本语言.如果你忘了填写用户名,它就跳出一个警告. 如今,它变得几乎无所不能,从前端到后端,有着各种匪夷所思的用途.程序员用它完成越来越 ...
- Atitit.javascript 实现类的方式原理大总结
Atitit.javascript 实现类的方式原理大总结 1. 实现类的式::构造方法方式:原型方式:构造方法+原型的混合方式 1 2. 原型方式(function mode)经典式..实现属性推荐 ...
- [转]Javascript定义类的三种方法
作者: 阮一峰 原文地址:http://www.ruanyifeng.com/blog/2012/07/three_ways_to_define_a_javascript_class.html 将近2 ...
- javascript 定义类(转载)
Javascript本身并不支持面向对象,它没有访问控制符,它没有定义类的关键字class,它没有支持继承的extend或冒号,它也没有用来支持虚函数的virtual,不过,Javascript是一门 ...
- javascript定义类和类的实现
首先说说类,在一个类里我们会有以下的几个特征: 1. 公有方法 2. 私有方法 3. 属性 4. 私有变量 5. 析构函数 我们直接看一个例子: /***定义类***/ var Class = fun ...
- javascript创建类的6种方式
javascript创建类的7种方式 一 使用字面量创建 1.1 示例 var obj={}; 1.2 使用场景 比较适用于临时构建一个对象,且不关注该对象的类型,只用于临时封装一次数据,且不适合代码 ...
- JavaScript一个类继承中实现
JavaScript类是默认原型对象继承: var Person = function() { this.name = "people"; this.hello = functio ...
- Javascript创建类和对象
现总结一下Javascript创建类和对象的几种方法: 1.原始的创建方法: <script type="text/javascript"> var person = ...
- JavaScript 定义 类
JavaScript 定义 类 一 构建类的原则 构造函数 等于 原型的constructor //构造函数 function Hero(name,skill){ this.name = name; ...
随机推荐
- hdu2102(bfs)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2102 分析:bfs求最短时间到达'P'点,不过本题有好几个trick,我都踩到了,自己还是太嫩了... ...
- cocos2d-x 消类游戏,类似Diamond dash 设计
前几天刚刚在学习cocos2d-x,无聊之下自己做了一个类似Diamond dash的消类游戏,今天放到网上来和大家分享一下.我相信Diamond dash这个游戏大家都玩过,游戏的规则是这样的,有一 ...
- MVC数据验证使用小结
原文:MVC数据验证使用小结 描述:MVC数据验证使用小结 内容:display,Required,stringLength,Remote,compare,RegularExpression 本人最近 ...
- Java算法分析1—————寻找数组同样元素
算法的两个评測指标:执行时间和内存消耗 要么用时间换空间,要么用空间换时间 寻找数组同样元素測试一: 0~99共100个元素各不同样,新增加一个0~99的元素不明白位置 从101个元素数组中找出与0~ ...
- mini2440裸试验—计算器(LCD显示,触摸屏突破)
关于Pait_Bmp(x0, y0, x, y, BMPaddr);函数 像素图在屏幕左上角为(0,0),Pait_Bmp中的x0.y0分别像素点初始位置,x,y为BMP图片的X,Y的大小.BMPad ...
- struts(二)——struts框架实现的基本原理
上一篇文章,我们介绍了MVC框架的基本原理,并指出了这个基本框架中存在大量if…else的问题.今天我们来介绍一下struts框架,让struts解决这个问题. 首先,看一下粗略的时序图: Actio ...
- 用EnableMenuItem不能使菜单变灰的原因
为何不能Disable菜单项 问:我有一个工具button在WM_COMMAND消息是这样做的: CMenu *pMenu = GetMenu(); pMe ...
- 【PhotoShop】采用PS让美丽的咖啡泡沫
稀土一杯咖啡,如何你不能击败张(常苦黑咖啡饮料实在受不了! ) 得到例如以下图 看着还不错,但是总感觉空空荡荡的,所以就拿来PS练手了.终于效果图例如以下: 以下讲下制作过程: 首先是给照片加下咖啡泡 ...
- uva11922(强行用rope替代spaly)
spaly没学过,用rope水过, rope是extension库中的东西,codeblocks编译器支持, 需要包含 #include <ext/rope>using namespace ...
- 【Android】应用启动画面
几乎所有的Android应用程序都会有一个启动画面,展示自己的LOGO,本版信息,或者更人性化一点的,在很长的加载信息中,变换一些显示的文字等,让无聊的等待时间添加点调味剂. 具体实现来说,应该创建一 ...