[读书笔记]JavaScript面向对象编程

简介:
摘要:

      我们在开发Web程序时或多或少都会应用到Javascript脚本程序,在当今的AJAX如此盛行的时代,JS的作用将不断的提升。这个新一代的 Web 应用程序的复杂性和交互性需要程序员以完全不同的方法来编写JavaScript 代码,我们在编写一次性的脚本显然已经不能够满足这样的需求。面向对象编程 (OOP) 是一种流行的编程方法,很多 JavaScript 库中都使用这种方法,以便更好地管理和维护基本代码。我们可以从ASP.NET AJAX库或SilverLight库以及经常见到的prototype.js库等等都采用了这种编程方式。JS支持OOP,但是又和C++,C#等非常不一样,所以这种概念一直会让人难以琢磨,这编文章将讲述 JavaScript 语言实际上如何支持面向对象编程,我们又如何应用这种方式来编写我们JS程序。
 

JavaScript对象

      在.NET中我们知道,万物皆为对象,也就是类实例化后得到的就是对象,每个对象都有各自不同的属性和方法。JavaScript中的对象和他有所不同,我们知道在JS中我们可以通过.[]运算符来获取或设置对象中的方法或属性,我们可以把它想象为包含键/值对的字典。下面我们来看个例子:
1 None.gif var  obj  =   new  Object();
2 None.gifobj.Now =   new  Date();
3 None.gifalert(obj.Now); 

      我们可以用[]运算符来达到同样的效果:
1 None.gif var  obj = new  Object();//{};
2 None.gifobj[ " Now " ] = new  Date();
3 None.gifalert(obj.Now);

      我们还可以直接定义它的属性,效果一样:
1 ExpandedBlockStart.gif var  obj = {"Now"new Date()} ;
2 None.gifalert(obj.Now);

     以上三种方法都能够达到同样得效果,如果你用过C#3.0他的匿名赋值就有点像,也许它就是跟JS学的(只是猜测)。您不必预先声明属性Now — 如果 obj 没有该名称的属性,该属性将被直接添加到 obj。这是不是很像字典,我们可以不断地往字典里加入键/值对,我想把它想象成字典最容易理解多了。

JavaScript函数

     在上面所讲述的是对象的属性,我们可以把属性值直接付给一个键(名称),其实JS的方法也是这样。JavaScript 函数实际上是具有与它关联的可执行代码的对象,我们定义方法时可以把我们的函数符给一个对象(类)中的名称(方法名称)。对于方法我想大家应该都很熟悉,这里就不多说了。

JavaScript原型

     在使用 JavaScript 的面向对象编程中,原型对象是个核心概念。在 JavaScript 中对象是作为现有示例(即原型)对象的副本而创建的,该名称就来自于这一概念。此原型对象的任何属性和方法都将显示为从原型的构造函数创建的对象的属性和方法。可以说,这些对象从其原型继承了属性和方法。

      在 JavaScript 中,每个函数都有名为“prototype”的属性,用于引用原型对象。此原型对象又有名为“constructor”的属性,它反过来引用函数本身。  当我们用用new创建对象时,所创建的对象将继承此函数的prototype属性。

       每个 JavaScript 对象都继承一个原型链,而所有原型都终止于 Object.prototype。当您尝试访问对象的属性/方法时,JavaScript 将检查该属性/方法是否是在该对象中定义的。如果不是,则检查对象的原型。如果还不是,则检查该对象的原型的原型,如此继续,一直检查到 Object.prototype。所以我想如果用很长的prototype链对于性能方面应该会有所影响,但是现在的客户端足以承受,因此在ASP.NET AJAX中用了相当大的prototype。

JavaScript闭包

       由于我对这个概念也不是特别的熟悉这个咚咚,它是JavaScript的一个高级功能,闭包是当内部函数绑定到它的外部函数的本地变量时所发生的运行时现象,这很容易让我们想到在C#中匿名的方法。我们可以通过一下实例来更好的理解这个功能:
1 None.gif var  isMoreThan300  =  filter(
2 ExpandedBlockStart.gif     function (x)  return (x > 300? true : false; }
3 None.gif    num);
4 None.gif

       以上事例说明了当前数num是否比300大,如果比300大我们就返回true,否则反回false。但我们可能还需要判断是否比400,500,200...等时,我们可以通过下列方法来完成:
 1 ExpandedBlockStart.gif function  makeMoreThan(lowerBound)  {
 2ExpandedSubBlockStart.gif    return function(numberToCheck) {
 3InBlock.gif        return (numberToCheck > lowerBound) ? true : 
 4InBlock.gif
 5InBlock.giffalse;
 6ExpandedSubBlockEnd.gif    }
;
 7ExpandedBlockEnd.gif}

 8 None.gif
 9 ExpandedBlockStart.gif function  filter(pred, numberToCheck)  {
10InBlock.gif    return pred(numberToCheck);
11ExpandedBlockEnd.gif}

12 None.gif
13 None.gif
14 None.gif var  isMoreThan10  =  makeMoreThan( 10 );
15 None.gif var  isMoreThan100  =  makeMoreThan( 100 );
16 None.gifalert(filter(isMoreThan10, 1 ));
17 None.gifalert(filter(isMoreThan100, 111 ));

       上面的代码运行后返回的结果是:false;true。从上面的代码可以看出makeMoreThan这个方法返回的是匿名函数,而这个匿名函数接受一个参数numberToCheck。根据作用域规则,当函数makeMoreThan退出时,变量lowerBound将失效,然而返回的匿名方法仍然带着lowerBound甚至在makeMoreThan结束后很长的一段时间内仍是如此。这样我们就可以利用这个特性来模拟.NET等中的私有变量,代码如下:
1 ExpandedBlockStart.gif function  Person(name)  {
2ExpandedSubBlockStart.gif    this.getName = function() return name; };
3ExpandedSubBlockStart.gif    this.setName = function(newName) { name = newName; };
4InBlock.gif    var gender;         
5ExpandedSubBlockStart.gif    this.getGender = function() return gender; };
6ExpandedSubBlockStart.gif    this.setGender  = function(newGender) { gender = newGender; };

       然后我们就可以调用Person中的方法给变量赋值,而其中的name和gender则就是我们的私有变量,当然这和.NET中所说的私有变量肯定是不同的。

Javascript继承

       在OOP中继承是不可少的,在C#中要继承某个类只要用:运算符就可继承,但是在Javascript中可没有那么简单,我们还需要写点代码才能够达到此效果。通过下面的例子就能够很好的说明:
 
 1 ExpandedBlockStart.gif function  Person(name) {
 2ExpandedSubBlockStart.gif   this.getName = function(){return name;};
 3ExpandedSubBlockStart.gif   this.setName = function(newName){name = newName;};
 4ExpandedBlockEnd.gif}

 5 None.gif
 6 ExpandedBlockStart.gifPerson.prototype.toString  =   function () {
 7InBlock.gif   return "My name is:" + this.getName();
 8ExpandedBlockEnd.gif}

 9 None.gif
10 ExpandedBlockStart.gif function  XiaMenPerson(name,address) {
11InBlock.gif   Person.call(this,address);
12ExpandedSubBlockStart.gif   this.getAddress = function(){return address;};
13ExpandedBlockEnd.gif}

14 None.gif
15 None.gifXiaMenPerson.prototype  =   new  Person();//继承prototype链
16 None.gif
17 None.gifXiaMenPerson.prototype.constructor  =  XiaMenPerson;//指定当前构造函数
18 None.gif//重写toString()方法,调用基类中的getName属性。
19 ExpandedBlockStart.gifXiaMenPerson.prototype.toString  =   function () {
20InBlock.gif   return "My name is:"+this.getName()+"\nCome from:"+this.getAddress();
21ExpandedBlockEnd.gif}
;
22 None.gif
23 None.gif var  p  =   new  Person( " 网魂小兵 " );
24 None.gifalert(p);
25 None.gif // My name is:网魂小兵
26 None.gif var  xp  =   new  XiaMenPerson( " 网魂小兵 " , " 厦门 " );
27 None.gifalert(xp);
28 None.gif // My name is:网魂小兵
29 None.gif// Come from:厦门
30 None.gif alert(xp  instanceof  XiaMenPerson); // true;
31 None.gif alert(xp  instanceof  Person); // true;
32 None.gif alert(xp  instanceof  Object); // true;

     本文转自网魂小兵博客园博客,原文链接:http://www.cnblogs.com/xdotnet/archive/2007/05/20/js_oop_program.html,如需转载请自行联系原作者
相关文章
|
1月前
|
JavaScript 前端开发 Java
深入JS面向对象(原型-继承)(三)
深入JS面向对象(原型-继承)
36 0
|
1月前
|
JavaScript 前端开发 Java
深入JS面向对象(原型-继承)(一)
深入JS面向对象(原型-继承)
38 0
|
1月前
|
存储 前端开发 JavaScript
揭秘原型链:探索 JavaScript 面向对象编程的核心(下)
揭秘原型链:探索 JavaScript 面向对象编程的核心(下)
揭秘原型链:探索 JavaScript 面向对象编程的核心(下)
|
1月前
|
前端开发 JavaScript 开发者
揭秘原型链:探索 JavaScript 面向对象编程的核心(上)
揭秘原型链:探索 JavaScript 面向对象编程的核心(上)
揭秘原型链:探索 JavaScript 面向对象编程的核心(上)
|
1月前
|
存储 JavaScript 前端开发
构造函数和原型的结合应用:轻松搞定JS的面向对象编程(三)
构造函数和原型的结合应用:轻松搞定JS的面向对象编程
|
1月前
|
设计模式 JavaScript 前端开发
构造函数和原型的结合应用:轻松搞定JS的面向对象编程(一)
构造函数和原型的结合应用:轻松搞定JS的面向对象编程
|
1月前
|
存储 JavaScript 前端开发
构造函数和原型的结合应用:轻松搞定JS的面向对象编程(二)
构造函数和原型的结合应用:轻松搞定JS的面向对象编程
|
3天前
|
设计模式 JavaScript 前端开发
【JavaScript】深入浅出JavaScript继承机制:解密原型、原型链与面向对象实战攻略
JavaScript的继承机制基于原型链,它定义了对象属性和方法的查找规则。每个对象都有一个原型,通过原型链,对象能访问到构造函数原型上的方法。例如`Animal.prototype`上的`speak`方法可被`Animal`实例访问。原型链的尽头是`Object.prototype`,其`[[Prototype]]`为`null`。继承方式包括原型链继承(通过`Object.create`)、构造函数继承(使用`call`或`apply`)和组合继承(结合两者)。ES6的`class`语法是语法糖,但底层仍基于原型。继承选择应根据需求,理解原型链原理对JavaScript面向对象编程至关重要
22 7
【JavaScript】深入浅出JavaScript继承机制:解密原型、原型链与面向对象实战攻略
|
11天前
|
前端开发 JavaScript 安全
TypeScript作为一种静态类型的JavaScript超集,其强大的类型系统和面向对象编程特性为微前端架构的实现提供了有力的支持
【6月更文挑战第11天】微前端架构借助TypeScript提升开发效率和代码可靠性。 TypeScript提供类型安全,防止微前端间通信出错;智能提示和自动补全加速跨代码库开发;重构支持简化代码更新。通过定义公共接口确保一致性,用TypeScript编写微前端以保证质量。集成到构建流程确保顺利构建打包。在微前端场景中,TypeScript是强有力的语言选择。
28 2
|
10天前
|
JavaScript 前端开发
深入解析JavaScript中的面向对象编程,包括对象的基本概念、创建对象的方法、继承机制以及面向对象编程的优势
【6月更文挑战第12天】本文探讨JavaScript中的面向对象编程,解释了对象的基本概念,如属性和方法,以及基于原型的结构。介绍了创建对象的四种方法:字面量、构造函数、Object.create()和ES6的class关键字。还阐述了继承机制,包括原型链和ES6的class继承,并强调了面向对象编程的代码复用和模块化优势。
22 0