javascript面向对象之我解

今天要用js实现一些客户端功能,考虑到业务逻辑,使用OO的开发方式会很方便,于是认真查看了相关的几篇文章,有一些心得体会。

首先是定义类。js中定义类是使用function,实例化使用new操作符:

function class1() {
this.a = 'class1';
   this.m1 = function() {
    alert('class1.m1');
  }
}
class1.prototype.m2 = function() {
  alert('class1.m2');
}
var c1 = new class1();

在js中,Function和Object是两个最基础的类,js中的任何对象、实例、函数都同时是Function和Object的实例,这可以用instanceof来验证,这一点有特殊的作用,后面的一些魔法全靠这一点支撑。

function有两种用法,一种如上,是常用的形式;另一种是运行时动态创建,如

var add = new Function("x", "y", "return (x+y)");

创建的结果是一个Function对象。这可以解释我之前看到的“奇怪”的用法。如上,this.m1 = function() {...}的用法中,实际上后面的function句自动产生了一个匿名的function对象,然后赋值给m1属性,随即class1就具有了m1方法。之后又用class1.prototype.m2 = function(){...}句定义了m2方法,实际上也是得到了匿名的function对象,然后赋值给m2属性。当然,这两种定义方法的形式是由区别的,后面会讲到。既然得到的是一个对象,可以使用变量指代,当然就可以作为函数调用的参数了,也就可以轻松而自然的实现函数回调了。这比C#之类的语言实现回调更方便自然。

这里再多啰嗦一句,js类在定义的时候可以定义属性,如示例中的a属性。除此之外,实例的属性是可以动态添加的。如果使用c1.b = 'b',则c1自动具有了属性b。这种动态添加的属性是不会扩散到其他实例的,即如果有另一个实例c2,则c2仍然只有属性a而无属性b。

如上示例,任何类(class1)的函数有两种实现方式,一种的内联的方式,即在定义function的时候,将方法写在body中;另一种是使用prototype,可以在任何地方定义。对于类的实例(class1的实例c1),同时拥有这两种方式定义的方法。因为内联定义的优先级高,在实例调用方法时,首先查找内联定义,然后转到prototype的定义中查找。因此,prototype定义的方法会被内联定义覆盖掉。如果真的发生了方法覆盖,要想使用prototype定义的方法,至少有两种方法(以下假设class1中使用同时使用了上述两种形式定义了方法m1)。

第一种是使用delete,首先delete掉m1方法,根据优先级,自然delete掉的是内联的m1方法。什么,不明白为什么还能delete掉方法?首先。js是动态语言;其次,记住方法也只是一个function实例,在class1中只是一个特殊属性而已。

var c1 = new class1();
delete c1.m1; //去掉内联的m1方法
c1.m1(); //调用prototype的m1方法

第二种是使用apply方法。至于apply的使用方法,可以查看js手册。

var c1 = new class1();
class1.prototype.m.apply(c1); //使用prototype中定义的m方法代替c1的m方法

用new实例化的对象仍然同时是Function对象和Object对象,包括这两者的所有实例属性和方法。这里不是很好理解,想想看,我们定义的类同时是Function对象和Object对象的实例,然后实例化后,实例也同时是Function对象和Object对象的实例,有没有一点像父亲和儿子的爸爸是同一个人?呵呵,有点恶心了,还希望高手出来详细剖析一下Function对象和Object对象以及js里面的类型关系。

这里把js和ruby做个比较。js和ruby都有一个默认的全局对象,js中是Global对象,所用定义的全局变量和函数都是Global的成员。从这一点看,js也有一点oo的感觉(至少是形式上):-)。ruby中,同时存在class变量和实例变量,js也是。这种设计是脚本语言的优势,可以在运行时随时改变class的定义,非常灵活和强大。同时两种脚本中的所有类型都不是封闭的,而是开放的,用户可以给语言内置的所有类型添加额外的属性和方法。

另外闲扯一下有趣的话题:js的反射。js中任何对象(function和object)都可以使用如下方式遍历所有成员:

var info = typeof(obj)+'\n';
for(p in obj) {
  info += p + '\n';
}
alert(info);

同样使用反射,可以这样调用方法和属性:

alert(c1['a']);
c1['m1']();

时间: 2024-11-01 23:34:21

javascript面向对象之我解的相关文章

Javascript面向对象详解(第一部分)

一直想写一篇关于Javascript面向对象的文章,最近终于动工了,本来以为不会写的很长,可是后来发现有很多东西要写,大家先看着这前面的一部分吧,后面有更多的高级特性陆续跟进中,放心,绝对不是太监贴啊,对Javascript对象不太了解或者没有了解的人可以仔细看看哦,有错误之处大家多多指正哦,本人水平有限 (1)为什么要面向对象 在十年前或者也许更晚的时候,javascript都是一种被人当作玩具来使用的语言,大多时候,没有人乐于深入研究它的特性,而只是用它来实现各种花里胡哨的特效来炫耀自己的技

JavaScript面向对象继承基础讲解

说好的讲解JavaScript继承,可是迟迟到现在讲解.废话不多说,直接进入正题.   既然你想了解继承,证明你对JavaScript面向对象已经有一定的了解,如还有什么不理解的可以参考详解JavaScript中面向对象基础知识,接下来讲一般通过那些方法完成JavaScript的继承.   原型链   JavaScript中实现继承最简单的方式就是使用原型链,将子类型的原型指向父类型的实例即可,即"子类型.prototype = new 父类型();",实现方法如下:  // 为父类型

JS面向对象编程详解_javascript技巧

序言 在JavaScript的大世界里讨论面向对象,都要提到两点:1.JavaScript是一门基于原型的面向对象语言 2.模拟类语言的面向对象方式.对于为什么要模拟类语言的面向对象,我个人认为:某些情况下,原型模式能够提供一定的便利,但在复杂的应用中,基于原型的面向对象系统在抽象性与继承性方面差强人意.由于JavaScript是唯一一个被各大浏览器支持的脚本语言,所以各路高手不得不使用各种方法来提高语言的便利性,优化的结果就是其编写的代码越来越像类语言中的面向对象方式,从而也掩盖了JavaSc

Javascript面向对象编程_js面向对象

Javascript的重要性 使用率 1.在web应用中,涉及到前端界面编程基本上都要用到javascript语言: 2.Web2.0及Ajax推动了javascript语言. 3.随着大量的c/s应用转向b/s,富客户端技术的不断推广,javascript语言的应用范围还将不断加大: javascript的特点 简单 动态 基于对象(面向对象) Javascript面向对象概述 Javascript是一种面向(基于)对象的动态脚本语言,是一种基于对象(Object)和事件驱动(EventDri

初步了解javascript面向对象_javascript技巧

前言 基于类的对象:我们都知道面向对象的语言中有一个明显的标志,就是都有类的概念,通过类这个类似模板的东西我们可以创建许多个具有相同的属性和方法的对象.然而在ECMAScript中并没有类的概念,自然它与基于类的语言中的对象也会有所不同. js中的对象: 无序 的属性的集合,属性可以包含基本值.对象.函数.即js中的对象是一组没有特定顺序的值,对象的每个属性或者方法都有一个自己的名字,而每个名字都与一个值相对应. 理解对象 创建对象的方式 1 创建一个对象的最简单的方式是创建一个Object实例

PHP面向对象编程详解:类和对象

PHP面向对象编程详解:类和对象 从OOP的视角看,不应区分语言.无论是C++.无论是Java.无论是.net还有更多面向对象的语言,只要你了解了OO的真谛,便可以跨越语言,让你的思想轻松的跳跃.便没有对于Java..net.PHP 之间谁强谁弱的争执了. 希望这个介绍PHP5面向对象编程(OOP)的资料能让初学者受益,能让更多的PHPer开始转向OO的编程过程. 相对PHP4,PHP5在面向对象方面改变了很多.我们将只介绍PHP5环境下的面向对象.而我们必须改变自己来跟随PHP5的发展.如果代

js面向对象 编程: JavaScript 面向对象编程,严格过程的标准化编程法,目前为止最好的 JS 生成对象代码结构

市面上流行了很多 JavaScript 面向对象的编程方法,其中不少都有好些问题.这里总结最正确的 JavaScript 面向对象编程模式.对于类 Special 继承自类 Common 继承自类 Super 的情况,一个 Special 对象的创建,详细说来,应该经历以下步骤.1 确定继承关系1.1 读取 Special 的父类,发现是 Common1.2 读取 Common 的父类,发现是 Super1.3 读取 Super 的父类,发现没有了(隐形父类 Object)2 加载类结构(如果没

JavaScript运算符实例详解

核心提示:JavaScript运算符实例详解 根据处理对象的数目: 单元运算符; 二元运算符; 三元运算符. 根据功能: 赋值运算符; = += -= *= /= %=(取余) 算术运算符; + - * / %(取余) ++(递增) --(递减) - 例1: 例2: <Script> var x = y = 3;  with (document) {      write("x = 3, y = 3 <br>");      write("若x = y

JavaScript面向对象的支持(4)

javascript|对象 ================================================================================Qomolangma OpenProject v0.9 类别    :Rich Web Client关键词  :JS OOP,JS Framwork, Rich Web Client,RIA,Web Component,          DOM,DTHML,CSS,JavaScript,JScript 项目发