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的"类"的更多相关文章

  1. 详解javascript的类

    前言 生活有度,人生添寿. 原文地址:详解javascript的类 博主博客地址:Damonare的个人博客 Javascript从当初的一个"弹窗语言",一步步发展成为现在前后端 ...

  2. Javascript定义类(class)的三种方法

    将近20年前,Javascript诞生的时候,只是一种简单的网页脚本语言.如果你忘了填写用户名,它就跳出一个警告. 如今,它变得几乎无所不能,从前端到后端,有着各种匪夷所思的用途.程序员用它完成越来越 ...

  3. Atitit.javascript 实现类的方式原理大总结

    Atitit.javascript 实现类的方式原理大总结 1. 实现类的式::构造方法方式:原型方式:构造方法+原型的混合方式 1 2. 原型方式(function mode)经典式..实现属性推荐 ...

  4. [转]Javascript定义类的三种方法

    作者: 阮一峰 原文地址:http://www.ruanyifeng.com/blog/2012/07/three_ways_to_define_a_javascript_class.html 将近2 ...

  5. javascript 定义类(转载)

    Javascript本身并不支持面向对象,它没有访问控制符,它没有定义类的关键字class,它没有支持继承的extend或冒号,它也没有用来支持虚函数的virtual,不过,Javascript是一门 ...

  6. javascript定义类和类的实现

    首先说说类,在一个类里我们会有以下的几个特征: 1. 公有方法 2. 私有方法 3. 属性 4. 私有变量 5. 析构函数 我们直接看一个例子: /***定义类***/ var Class = fun ...

  7. javascript创建类的6种方式

    javascript创建类的7种方式 一 使用字面量创建 1.1 示例 var obj={}; 1.2 使用场景 比较适用于临时构建一个对象,且不关注该对象的类型,只用于临时封装一次数据,且不适合代码 ...

  8. JavaScript一个类继承中实现

    JavaScript类是默认原型对象继承: var Person = function() { this.name = "people"; this.hello = functio ...

  9. Javascript创建类和对象

    现总结一下Javascript创建类和对象的几种方法: 1.原始的创建方法: <script type="text/javascript"> var person = ...

  10. JavaScript 定义 类

    JavaScript 定义 类 一 构建类的原则 构造函数 等于 原型的constructor //构造函数 function Hero(name,skill){ this.name = name; ...

随机推荐

  1. cocos2d-x 贝塞尔曲线的简单运用(CCBezierTo,CCBezierBy)

    原文链接:http://blog.csdn.net/we000636/article/details/8616355 一.贝赛尔曲线简单介绍 贝塞尔曲线是应用于二维图形应用程序的数学曲线.曲线的定义有 ...

  2. hdu4027(线段树)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4027 线段树功能:区间修改,区间求和. 分析:因为每个数至多开6次平方就变1了,所以对于每一段全为1的 ...

  3. unity中的MonoBehaviour.OnMouseDown()

    在官网的api文档中仅说明了 Description OnMouseDown is called when the user has pressed the mouse button while ov ...

  4. 逆向 Framework.jar

    Ref:http://www.addictivetips.com/mobile/what-is-odex-and-deodex-in-android-complete-guide/ Ref:http: ...

  5. Java http数据MD5、AES、DES加密

    一,数据加密 1.提供了,md5,Hex,Sha等不可逆算法加密 2.AES加密,此加密方式瘦平台影响较重,所以只适合同类平台加密解密 3.DES自定义加密,跨平台,兼容性好 1.org.apache ...

  6. mybatis 打印SQL语句

    在log4j文件中配置 log4j.rootLogger=DEBUG log4j.logger.com.ibatis=DEBUG log4j.logger.org.mybatis=DEBUG  

  7. Mvc 异常处理 ajax的 和 不是ajax的!

    using ImageUpload.Auth; using System; using System.Collections.Generic; using System.Linq; using Sys ...

  8. [ACM] POJ 3259 Wormholes (bellman-ford最短路径,推断是否存在负权回路)

    Wormholes Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 29971   Accepted: 10844 Descr ...

  9. 2014牡丹江——Hierarchical Notation

    problemId=5380" style="background-color:rgb(51,255,51)">题目链接 字符串模拟 const int MAXN ...

  10. Apache的Mesos和Google的Kubernetes 有什么区别?

    Apache的Mesos和Google的Kubernetes 有什么区别?本文来自StackOverFlow上的一个问题,主要讨论Mesos和Kubernetes的区别,相信我们很多人也有同意的疑问. ...