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; ...
随机推荐
- BZOJ 1176([Balkan2007]Mokia-CDQ分治-分治询问)
1176: [Balkan2007]Mokia Time Limit: 30 Sec Memory Limit: 162 MB Submit: 185 Solved: 94 [ Submit] ...
- commons.net.telnet使用示例
import org.apache.commons.net.telnet.TelnetClient; import java.io.IOException; public class TelnetDe ...
- 阿里2016实习offer五面经验与总结(转)
前言 目前楼主已经拿到阿里实习offer,一共经历了5次面试,其中4轮技术面,1轮HR面试.在这里分享一下自己的面试经验和学习总结.写这篇面经主要是希望能够帮助更多的小伙伴.我本科毕业于中南大学信管专 ...
- Android-->发送短信页面实现(短信发送以及群发和从电话本中选择联系人)-----------》2
分析下怎么写 首先,我们需要一个输入框,可以手动的输入手机号码, 其次,很少有人愿意手动输入,那么我们需要提供一个按钮来给我们的用户选择自己电话本中的联系人(一次可以选择多个即群发) 然后,我们需要一 ...
- SE 2014年5月23日
两站点 A 和 B,由于业务往来需要,所以工程师提出vpn技术,同时需要保证业务流在internet上的安全性,同时在这里站点均为固定ip地址. 通过分析以上信息,确定这里使用 IPSec VPN的主 ...
- JSP网站开发基础总结《九》(转)
本篇属于附加篇,在之前的总结中给大家提到过一个关于登录状态验证的效果,当时是通过Session对象完成的,今天我查了一下,JSP为我们封装了一个用于过滤用的过滤器类Filter,通过它我们就可以非常轻 ...
- HDU 5066 Harry And Physical Teacher(物理题)
HDU 5066 Harry And Physical Teacher 思路:利用物理里面的动量守恒公式.因为保证小车质量远大于小球.所以能够把小车质量当成无穷大带进去,得到答案为2 * v0 - v ...
- Thread Dump 和Java应用诊断(转)
Thread Dump 和Java应用诊断 Thread Dump是非常有用的诊断Java应用问题的工具,每一个Java虚拟机都有及时生成显示所有线程在某一点状态的thread-dump的能力.虽然各 ...
- 关于bind函数和connect函数的测试结论
1. 一般客户端不用绑定,系统给你自动分配(有些ip不是固定的,bind也不是一个好方法):而服务器需要绑定,因为需要给客户端一个众所周知的固定的地址: 2. 关于bind错误,可以用WSAGetLa ...
- 工作经常使用的SQL整理,实战篇(三)
原文:工作经常使用的SQL整理,实战篇(三) 工作经常使用的SQL整理,实战篇,地址一览: 工作经常使用的SQL整理,实战篇(一) 工作经常使用的SQL整理,实战篇(二) 工作经常使用的SQL整理,实 ...