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; ...
随机推荐
- Deploy Oracle 10.2.0.5 DataGuard on Red Hat Enterprise Linux 6.4
系统:Red Hat Enterprise Linux 6.4 数据库:Oracle 10.2.0.5.0 Patch Set 4 主机:10dg1 192.168.1.91 10dg2192.168 ...
- finger用户名、主目录、停滞时间、登录时间
finger yum install finger 1.作用 finger用来查询一台主机上的登录账号的信息,通常会显示用户名.主目录.停滞时间.登录时间.登录Shell等信息,使用权限为 ...
- mysql sqlserver Oracle字符串连接
mysql 例mysql> select CONCAT('My', 'S', 'QL'); sqlserver select name+'aa' from student; oracle sel ...
- C#获取设备的IP和Mac类
/// <summary> /// 此类用于获得设备的Ip和Mac /// </summary> public class Mac { [DllImport("Iph ...
- 一般报java.lang.NullPointerException的原因有以下几种
一般报java.lang.NullPointerException的原因有以下几种: ·字符串变量未初始化: ·接口类型的对象没有用具体的类初始化,比如: List lt; 会报错 List lt = ...
- PageRank算法MapReduce实现
如果你现在需要计算网页的排名只有4一:数据如下面的: baidu 10.00 google,sina,nefu google 10.00 baidu sina 10.00 google nefu 10 ...
- IntelliJ IDEA常见问题解决办法汇总
(1)SVN相关的操作: 启用:方法1:VCS菜单下Enable Version Control Integration,点击之后选择相应的版本控制工具方法2:Setting中Version Cont ...
- ASP.NET中的ExecuteNonQuery()方法的用法
下面我将详细讲解在机房收费系统D层中如何对数据库的增加.删除.修改,最后再来总结一下 ExecuteNonQuery(),ExecuteScalar(),ExecuteReader的用法: 一.增.删 ...
- HDU1163 Eddy's digital Roots【九剩余定理】
Eddy's digital Roots Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Oth ...
- 游戏碰撞OBB算法(java代码)
业务需求 游戏2D型号有圆形和矩形,推断说白了就是碰撞检测 : 1.圆形跟圆形是否有相交 2.圆形跟矩形是否相交 3.矩形和矩形是否相交 ...