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. 基于Grunt的版本号构建系统新手教程

    作者:zhanhailiang 日期:2014-10-12 1. 安装nodejs,npm,grunt-cli.參见<Windows环境下安装nodejs+npm+grunt-cli工具> ...

  2. redis来共享各个服务器的session,并同时通过redis来缓存一些常用的资源,加快用户获得请求资源的速度(转)

    时间过得真快,再次登录博客园来写博,才发现距离上次的写博时间已经过去了一个月了,虽然是因为自己找了实习,但这也说明自己对时间的掌控能力还是没那么的强,哈哈,看来还需不断的努力啊!(这里得特别说明一下本 ...

  3. [poj 1127]Jack Straws[线段相交][并查集]

    题意: 给出一系列线段,判断某两个线段是否连通. 思路: 根据线段相交情况建立并查集, 在同一并查集中则连通. (第一反应是强连通分量...实际上只要判断共存即可, 具体的方向啊是没有关系的..) 并 ...

  4. 【译】ASP.NET MVC 5 教程 - 11:Details 和 Delete 方法详解

    原文:[译]ASP.NET MVC 5 教程 - 11:Details 和 Delete 方法详解 在教程的这一部分,我们将研究一下自动生成的 Details 和Delete 方法. Details ...

  5. 什么样的企业造什么样的软件最easy成功?

    事件1: 一般软件企业按功能分,大体分业务应用型软件和系统工具型软件. 按市场分,应用型软件企业较多,直接贴近生活:系统工具类较少,间接贴近大众较少. 事件2: 软件企业中,当中中小型企业老板存在非常 ...

  6. 【cocos2d-js官方文档】十、log

    api修改情况.左边为新增,右边为原来的. cc.log 不变 cc.warn 新增 cc.error 新增 cc.assert <-- cc.Assert 此次改造有下面几点原因: 加入原来没 ...

  7. linux su,sudo命令

    linux su 命令 建议大家切换用户的时候 使用 su - root 这样,否则可能发现某些命令执行不了 关于su .su - 及 sudo的区别 请往下看 1.命令作用 su的作用是变更为其它使 ...

  8. Resource temporarily unavailable用户的连接数设置的太小

    -bash:fork:Resource temporarily unavailable的问题   出现这个问题的原因是linux用户的连接数设置的太小,只要修改max user processes就可 ...

  9. 建立qemu桥接的网络连接

    转载请注明出处谢谢:http://www.openext.org/2014/07/qemu-kvm-bridge-00     安装桥接工具:sudo apt-get install bridge-u ...

  10. LeetCode18:4Sum

    Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = tar ...