`
wgj830823
  • 浏览: 49702 次
  • 性别: Icon_minigender_1
  • 来自: 青岛
社区版块
存档分类
最新评论

基于对象的JavaScript编程 1

阅读更多

基于对象的JavaScript编程

-JavaScript Object-Oriented Programming

                     By-Ryan Frishberg

接触ajax一直不是很深入,然后对于JavaScript的所谓基于对象的理解更是肤浅的很,g了很多中文的文章看着一头雾水,找了一篇2001年老外的文章看了看,我*!讲的既简单又涉及到了精髓,忍不住花了两天翻译了一下,这是第一部分,第二部分抽时间也去翻一下,本人英文水平处于"伦敦郊区"水平,大家多喷。-.-

这个可能让你很震惊,但是JavaScript是一种很强大的基于对象(object-based或者prototype-based,随便你怎么称呼)的编程语言。的确如此,JavaScript是一种强大的编程语言,并不是只能制造图片滚动效果和平淡或华丽的展现效果。可是,很少使用者能认识到JavaScript潜在的强大的功能。如果你恰恰属于这个行列,那这篇文章正好适合你。

首先,JavaScriptjava一样不是一门纯粹的OOPObject-Oriented-Programming)语言,但是它是一门基于对象的编程语言。但是,你为什么要用JavaScript的对象呢?原因是这样你不仅能熟悉JavaScript的工作原理,而且在编写脚本时,你还可以自己创建JavaScript对象,而不总是像你现在这样只编写一些顺序执行的代码。这些编写的JavaScript对象你也可以在以后重复利用。

       我希望这篇文章能够促成那些渴望学习面向对象技术的中级JavaScript工程师形成对JavaScript面向对象世界的持续兴趣,从而成为专家。

     在这篇导读里,你能学到:

*         JavaScript的基本数据类型(JavaScript's primitive data types

*       JavaScript中什么是对象(What an object is in JavaScript

*       怎样创建一个普通的对象(How to create custom objects

*       构造器是什么(What a constructor is

*       对象的基本属性是什么(What an object's prototype property is

JavaScript的基本数据类型

JavaScript有五种基本数据类型:

           Undefined

           Null

           Boolean

           Number

           String

       在这篇导读中,我们会大量的用到后面三种类型

Boolean 类型是一种包含或者true或者false两种值的逻辑实体。例如:

var BooleanValue = true;

Number类型是一种用来描述数的大小的一组数值。例如:

var NumericalValue = 354;

String 类型是一组包含零到多个字符的类型。例如:

var StringValue = "This is a String";

Typeof

typeof JavaScript中一个常用的操作符。它能告诉你正在操作的数据的类型。这有意义吗?让我们来看几个例子:

var BooleanValue = true;
var NumericalValue = 354;
var StringValue = "This is a String";
alert(typeof BooleanValue) //
显示 "boolean"
alert(typeof NumericalValue) //
显示 "number"
alert(typeof StringValue) //
显示 "string"

对象

对象是属性的集合。这些属性可以是基本数据类型,其他的对象或者是函数(这里先暂时称为方法,后面会有别的名称)。构造函数(简单说是构造器)是一种用来创建一个对象的方法——这个我们会在后面详细讨论。JavaScript有许多内置的对象,如:Array, Image, Date对象。你们很多人都很熟悉怎样使用Image对象来构建华丽的滚动效果。那么,当你使用这些代码:

var Image1 = new Image();  
Image1.src = "myDog.gif";

事实上你已经创建了一个Image对象,并且给你自己的 Image对象设置了一个属性值:src属性。Image1是一个新的Image对象;换句话说,它是一个Image类型的实例。使用JavaScript中的‘.’符号,上面代码就取得了你自己的image对象的src属性并设置了它的值。现在,我们来学习怎么创建自己的对象:

function myFunc(){  
}  
 
var myObject = new myFunc();  
alert(typeof myObject);  //
显示 "object"

我们刚刚创建了自己的对象。事实上我们已经构建了一个myFunc对象的实例,myFunc()是一个构造方法;构造方法指出了该对象在被创建时要进行的初始化工作,尽管我们这个构造方法里没有什么初始化的工作(原文:it lays out the blueprint from which objects that are created from it will follow (although, in this case, it doesn't lay out much of a blueprint).)。这样,JavaScript是怎样知道要创建一个myFunc的对象,而不是返回这个方法的返回值的呢?让我们来比较一下上面的例子和下面这个,一般方法更经常的用法:

function myFunc(){  
 return 5;  
}  
 
var myObject = myFunc();  
alert(typeof myObject); //
显示 "number"

当前的这个例子里,我们把5赋值给了myObject,这样,这两段脚本的区别在哪呢?答案:new关键字。就是它告诉了JavaScript的编译器遵循myFunc()构造方法中设置的初始化内容创建了一个对象。事实上,当我们创建了一个Image对象,我们也进行了相同的过程,只不过这里用了自己的构造方法而已,而在创建Image对象是用了JavaScript内置的Image()构造方法。

到目前为止,我们已经学习了怎样建一个构造函数,怎样用这个构造函数去构建一个对象实例。在我们的例子里,我们创建了一个myFunc()构造器,并且创建了一个myFunc对象的实例,并把它赋给了变量myObject

     这些都很好很强大,但是什么才是关键呢?是的,就像我们给Image对象添加属性那样,myObject也可以被分配各种各样的属性:

function myFunc(){  
}  
 
var myObject = new myFunc();  
myObject.StringValue = "This is a String";  
alert(myObject.StringValue); //
显示 "This is a String"

瞧,现在我们已经给我们自己的对象添加了一个属性。可是,当我们新建一个myFunc对象的实例时(用构造方法myFunc()),我们也必须要手动的将同样的属性赋值给新的实例,例如:

function myFunc(){  
}  
 
var myObject = new myFunc();  
myObject.StringValue = "This is a String";  
var myObject2 = new myFunc();  
alert(myObject2.StringValue); //
显示 "undefined"

那么,我们应该怎么操作才能给所有的myFunc对象实例添加属性呢?在操作方法内部,我们就可以做到。this这个关键字在构造方法内部的时候指向当前正被创建的对象实例。例如:

function myFunc(){  
 this.StringValue = "This is a String";  
}  
 
var myObject = new myFunc();  
var myObject2 = new myFunc();  
alert(myObject2.StringValue); //
显示 "This is a String"

现在,所有的myFunc对象都会有一个初始值为“this is a String”的字符串型的属性StringValue,同时每个对象实例的属性StringValue都可以拥有自己独特的值。也就是说,我们可以改变任何一个myFunc对象实例的stringValue属性的值,而不影响其他的myFunc实例:

function myFunc(){  
 this.StringValue = "This is a String";  
}  
 
var myObject = new myFunc();  
myObject.StringValue = "This is myObject's string";  
var myObject2 = new myFunc();  
alert(myObject.StringValue); //
显示 "This is myObject's string"  
alert(myObject2.StringValue); //
显示 "This is a String"

     通过给构造方法添加参数的方法我们也可以达到相同的效果:

function myFunc(StringValue){  
 this.StringValue = StringValue;  
}  
 
var myObject = new myFunc("This is myObject's string");  
var myObject2 = new myFunc("This is a String");  
alert(myObject.StringValue); //
显示 "This is myObject's string"  
alert(myObject2.StringValue); //
显示 "This is a String"

myFunc()构造方法中,this.StringValue 指向当前创建的对象实例的StringValue属性,而StringValue则指向做为参数传过来的该方法的局部变量。这样,我们就把属性指向了对象实例,那方法有如何呢?(附:In the myFunc() constructor, this.StringValue refers to the property being assigned to the newly created object, while StringValue refers to the function's local variable that was passed as an argument. So, now that we've assigned properties to objects, what about methods?

原文里functionmethod翻译起来费劲,还是看一下原文吧要是没读懂。--

对象方法

     除了属性以外,对象也可以包含方法,对象的方法是一个可以执行的函数。来看看这个例子。下面这个例子中,我们创建一个Circle对象。首先我们要定义几个函数,然后将他们指定给我们的Circle对象。现在我们来定义Circle()构造函数,同时创建一到两个它的具体实例:,

function Circle(radius){  
 this.radius = radius;  
}  
 
var bigCircle = new Circle(100);  
var smallCircle = new Circle(2);

然后,我们再定义两个可能用到的函数:

function getArea(){  
 return (this.radius*this.radius*3.14);  
}  
 
function getCircumference(){  
 var diameter = this.radius*2;  
 var circumference = diameter*3.14;  
 return circumference;  
}

如果你要进行精确的计算的话,你可以用Math.PI来替代3.14,但这里我们就用pi的近似值来增强例子的可读性。

     除了一个内容外这些函数都很简单:this.radius指向什么内容?this这个关键字总是指向当前对象,在这个例子里就是这个Circle对象。所以this.radius就指向了这个Circle对象的radius属性。那么,我们怎样将这两个函数添加到我们的对象中呢?事实上它没有你想象的那么麻烦。我们先来改改我们的Circle()构造器:

function Circle(radius){  
 this.radius = radius;  
 this.getArea = getArea;  
 this.getCircumference = getCircumference;  
}

上面的代码将函数getAreagetCircumference添加到我们的Circle对象上,从而他们就成了我们的Circle对象中的方法。我们可以像使用其他函数一样使用对象的方法,但是我们必须通过一个包含它的具体的对象实例来调用它:

alert(bigCircle.getArea()); // 显示 31400  
alert(bigCircle.getCircumference()); //
显示 618  
alert(smallCircle.getArea()); //
显示 12.56  
alert(smallCircle.getCircumference()); //
显示 12.56

保持整洁

如果我们想保持我们的属性和方法在相同的地方-Circle构造方法内部。有很多方法可以做到。先来看一下内部函数。内部函数就是在一个函数内部的函数。这是我们要做的:

function Circle(radius){  
 function getArea(){  
   return (this.radius*this.radius*3.14);  
 }  
 function getCircumference(){  
   var diameter = this.radius*2;  
   var circumference = diameter*3.14;  
   return circumference;  
 }  
this.radius = radius;  
this.getArea = getArea;  
this.getCircumference = getCircumference;  
}

除了方法的位置发生了变化其他都一样。现在在我们的两个函数内部,因为内部函数能取得包含它的外部函数的局部变量,我们用radius取代了this.radius。这样,它就能取得做为参数传递给外部函数Circle()构造器的局部变量了,这样我们就可以这样简单的使用了:

function Circle(radius){  
 function getArea(){  
   return (radius*radius*3.14);  
 }  
 function getCircumference(){  
   var diameter = radius*2;  
   var circumference = diameter*3.14;  
   return circumference;  
 }  
 this.radius = radius;  
 this.getArea = getArea;  
 this.getCircumference = getCircumference;  
}

oK,现在让我们来改变一下一个对象的radius的值,然后去的它的面积:

bigCircle.radius=50;  
alert(bigCircle.getArea()); //
显示 31400

瞧,先等等!返回值是31400,而不是期望的7850.哪里错了呢?好吧,radius引用了我们赋给构造方法的值,而不是对象的属性的值。这样我们虽然改变了对象的radius的值,但是方法getArea()和getCircumference(),还在使用旧的radius值。因此,我们应该使用指向了当前对象的this.radius,不管属性是在对象初始化的前后进行的改变。

     OK,我们已经创建了一个完整的对象构造器(定义了一个对象的函数)。我们再来看看另一种在我们Circle()构造器内部建立方法的途径:

function Circle(radius){  
 this.radius = radius;  
 this.getArea = function(){  
   return (this.radius*this.radius*3.14);  
 }  
 this.getCircumference = function(){  
   var diameter = this.radius*2;  
   var circumference = diameter*3.14;  
   return circumference;  
 }  
}  
 
var bigCircle = new Circle(100);  
var smallCircle = new Circle(2);  
 
alert(bigCircle.getArea()); // displays 31400  
alert(smallCircle.getCircumference()); // displays 12.56

在这里我们邂逅了另一种定义函数的法国是,我们可以这样做:

functionName = function([parameters]){  
 // function body  
}

我们可以这样来建参数:

functionName = function(parameter1,parameter2,parameter3){  
 //function body  
}

尽管这种建立函数的方法不是很常用,但是在建立对象时,这却是一个很好用的捷径。这个过程同样避免了同名方法的出现。例如,另一个对象可以拥有一个同名的不同方法,如:getArea() 而不会产生冲突。这种可能是因为这些函数被嵌套在了类构造器里。

对象种类

JavaScript总共有三种对象:原生对象,宿主对象,以及用户自定义对象。

原生对象JavaScript自己内建的对象,如String,Number,Array,Image,Date,Math,等等。

宿主对象是浏览器支持的对象,如:windowdocumentforms等等

用户自定义对象就是程序员自己编写的对象了。

JavaScript中,除了基本数据类型任何一个包含属性和方法的元素都是对象是它的基本思想。我们可以使用JavaScript的内建构造方法(就像我们已经创建的那样)去创建对象。

var Image1 = new Image(50,100);    
Image1.src = "myDog.gif";

在这里我们使用了JavaScript自有的Image()构造函数创建了一个具有如下属性值的对象:

*       width = 50

*       height = 100

*       src = "myDog.gif"

JavaScript中也包含了一个基本的Object()构造器,也可以用它来创建一个对象:

var myObj = new Object();

我们可以给一个基本对象添加属性和方法,JavaScript中的所有对象都继承自JavaScript的基本的Object对象。

回顾一下一个基本数据类型的String

var myString = "This is my string";    
alert(myString); //
显示 "This is my string"    
alert(typeof myString); //
显示 "string"

同时,我们也可以创建一个String类型的对象,通过这样的构造方法:

var myString = new String("This is my string");    
alert(myString); //
显示 "This is my string"    
alert(typeof myString); //
显示 "object"

     现在我们构建了一个String类型的对象。我们也可以同样创建NumberBoolean类型的对象。但这样做又有什么好处呢?是的,一旦我们这样做了,就可以给这些对象添加独特的属性和方法。一个基本数据类型的实例包含了它的构造函数定义的属性和方法,但是它却不能拥有任何自己独有的属性和方法。例如,一个String基本类型就拥有length这个属性以及substring方法以及其它的通过它的构造函数获得的属性和方法。但是,一个String对象可以含有String()构造函数设置的属性和方法,也可以包含任何自己独有的特性。我们来创建一个Number对象,并给他添加一个方法:

var myNumber = new Number(2);    
myNumber.doubleIt = new Function("return this*2");    
alert(myNumber.doubleIt()); //
显示: 4    
alert(typeof myNumber); //
显示"object"

我们仅仅创建了一个新的Number的对象实例,为它定义了一个方法:doubleIt()。请注意myNumber是一个“类对象”。这是因为对象可以包含自己独有的属性和方法,但是基本数据类型,如StringBooleanNumberundefined,还有null却不能同样拥有。这是他们之间的区别。

可以看到,在上面的例子中,我们实际上创建了另外一个对象---一个Function对象。然而,这个Function对象是与众不同的。一般情况下,我们创建一个对象时,首先输入new关键字,然后紧跟着对象的构造函数,这样就可以返回一个普通的对象实例。接着我们就可以在生成的对象(通常用变量来保存)上添加属性和方法。可是,因为Function对象同时也是一整块可以调用的代码,JavaScript将它设置的与众不同,并且指出它不仅仅是一个对象(可以随意添加属性和方法),而且是一个可以调用的代码块。这样,当我们输入:

alert(typeof myNumber.doubleIt) // 显示 "function"

就像你希望的那样,显示了“function”而不是“object”。Function()构造函数可以接受一些参数(arguments)。除了最后一个参数成为了这个函数的函数体,其他的参数都成了你的函数的参数(parameters):

var myFunc = new Function("parameter1","parameter2",    
 "parameter3"," // function body");

现在我们可以传入三个参数来调用这个函数:

myFunc("argument1","argument2","argument3");

函数对象

因为很多原因JavaScriptFunction对象变得不同寻常。首先,它包含一整块可调用的代码。再者,一个函数对象还是一个完整的对象它总是有能力包含独特的属性和方法。建立函数时就自动的建立了一个Function对象:

function myFuncObj(){}    
myFuncObj.someVariable = "x";    
alert(myFuncObj.someVariable) //
显示 "x"  

即使没有使用new关键字,Function()构造函数还是创建了一个对象,一个普通的能包含属性和方法的对象。请注意Function()构造器是一个特殊的构造器其他的构造器都必须使用new关键字来调用,或者有一个简单数据类型的返回值而不是一个对象。

我们来看一下一个基本数据类型String,和一个String类的比较:

var pimitiveString1 = "This is a primitive string";    
var pimitiveString2 = String("This is a primitive string");    
var stringObject = new String("This is a String object");    
   
primitiveString1.prop = "This is a property";    
primitiveString2.prop = "This is a property";    
stringObject.prop = "This is a property";    
   
alert(primitiveString1.prop) //
显示 "undefined"    
alert(primitiveString2.prop) //
显示 "undefined"    
alert(stringObject.prop) //
显示 "This is a property"    
   
alert(typeof primitiveString1); //
显示 "string"    
alert(typeof primitiveString2); //
显示 "string"    
alert(typeof stringObject) //
显示 "object"

你可以看到,不适用new关键字,我们无法创建一个对象并将它赋给一个变量,取而代之的是它将一个返回的基本数据类型(String基本类型)赋给了那个变量。你也可以看到primitiveString1 primitiveString2都不是对象,这样我们就不能给他们添加属性。当使用typeof关键字时primitiveString1/primitiveString2 stringObject 返回了不一样的结果。其他的如Date, Image, Option, 还有其他的类也一样。例如:

var x = Date();    
alert(typeof x); //
显示 "string"

无论你怎么创建一个函数(很多方法)你会自动创建一个对象:

var myFuncObj = new Function();    
var myFuncObj = Function();    
var myFuncObj = function(){}    
function myFuncObj()

这里我们用了不同的方法创建了Function对象,他们都能够包含一块可以调用的代码,同时也可以包含自己的属性和方法。

小结

继续之前,让我们来看几个关键点:

*                   JavaScript包含五种基本数据类型:Undefined, Null, Boolean, Number, String.

*                   JavaScript中除了基本数据类型,一切都是对象。

*                   对象是属性的无序集合。属性可以表现为基本数据类型,对象,函数对象(这里一般称为方法)。

*                   总起来说JavaScript包含三种类别的对象,原生对象,宿主对象,以及用户自定义对象(就像我们前面定义的Circle对象)。

*                   对象构造器/构造函数是一个用来创建一个新的对象类型的函数。在这个函数中我们定义了一个对象的基本属性和方法,通常也给他们赋了初始值。

*                   可以使用new关键字调用构造器来创建一个对象的实例。我们既可以使用JavaScript内建的构造函数来创建一个原生对象,也可以使用自己定义的构造函数来创建一个自定义对象。

任何一个对象中都包含一个变量—this,它指向调用方法时候的那个实例对象,也就是当前对象,例如:

*                                           myObj.myFunc()

*                                           yourObj.myFunc()

第一个例子中,方法myFunc()中的this指向了myObj。而第二个例子中,myFunc()里的this是指向yourObj这个对象的。

 

 原文地址:http://articles.sitepoint.com/article/oriented-programming-1/1

2
1
分享到:
评论

相关推荐

    JavaScript基于对象编程

    JavaScript基于对象编程 JavaScript基于对象编程

    JavaScript面向对象编程指南

    资源名称:JavaScript面向对象编程指南内容简介: Javascript是一种具有高度表达能力的、基于原型特性的、非常灵活的面向对象编程语言。《Javascript面向对象编程指南》着重介绍Javascript在面向...

    基于对象的JavaScript编程 透彻

    接触ajax一直不是很深入,然后对于JavaScript的所谓基于对象的理解更是肤浅的很,g了很多中文的文章看着一头雾水,找了一篇2001年老外的文章看了看,我*!讲的既简单又涉及到了精髓,忍不住花了两天翻译了一下,这是...

    第4章+JavaScript基于对象编程.pdf

    第4章+JavaScript基于对象编程.pdf

    Javascript 面向对象编程

    Javascript是一种基于对象(object-based)的语言,你遇到的所有东西几乎都是对象。但是,它又不是一种真正的面向对象编程(OOP)语言,因为它的语法中没有class(类)。 那么,如果我们要把"属性"(property)和...

    基于闭包的JavaScript面向对象编程框架.pdf

    基于闭包的JavaScript面向对象编程框架.pdf

    JavaScript函数式编程

    JavaScript 是近年来非常受瞩目的一门编程语言,它既支持面向对象编程,也支持函数式编程。本书专门介绍JavaScript函数式编程的特性。 全书共9章,分别介绍了JavaScript函数式编程、一等函数与Applicative编程、...

    javascript DOM 编程艺术

    从颇具深度的JavaScript语言基础到作用域(链),从引用类型到面向对象编程,从极其灵活的匿名函数到闭包的内部机制,从浏览器对象模型(BOM)、文档对象模型(DOM)到基于事件的Web脚本设计,从XML(E4X)到Ajax及JSON,从...

    JavaScript面向对象编程指南(第2版)

    1.本书是唯一一本介绍JavaScript面向对象编程的图书。, 2.本书作者是知名的Web开发人员和作者。受到国内众多前端开发人员,如淘宝UED团队的推崇和推荐。 Stoyan Stefanov:Facebook公司工程师、作家、演说家。他经常...

    Javascript 高级编程第2版PDF part1

    从颇具深度的javascript语言基础到作用域(链),从引用类型到面向对象编程,从极其灵活的匿名函数到闭包的内部机制,从浏览器对象模型(bom)、文档对象模型(dom)到基于事件的web脚本设计,从xml(fax)到ajax及json,从...

    JavaScript面向对象编程

    Javascript是一种面向(基于)对象的动态脚本语言,是一种基于对象(Object)和事件驱动 (EventDriven)并具有安全性能的脚本语言。他具有面向对象语言所特有的各种特性,比如封 装、继承及多态等。但对于大多数人说,...

    javascript高级编程学习手册

    目录: 第一章 javascript语言概述 第二章 JavaScript语言基础 第三章 JavaScript事件处理 第四章 JavaScript基于对象编程 第六章 string,math,array等数据对象 第七章 window及相关顶级对象 第八章 document对象

    JavaScript脚本特效编程给力起飞

    JavaScript是一种基于对象和事件驱动并具有相对安全性的客户端脚本语言。同时也是一种广泛用于客户端Web开发的脚本语言,常用来给HTML网页添加动态功能,比如响应用户的各种操作。Javascript提供了丰富的运算功能,...

    Javascript面向对象编程

    javascript的特点 简单 动态 基于对象(面向对象) Javascript面向对象概述 Javascript是一种面向(基于)对象的动态脚本语言,是一种基于对象(Object)和事件驱动(EventDriven)并具有安全性能的脚本语言。他具有面向...

    讲解JavaScript的面向对象的编程

    本人一行注释一行代码翻译了该大师的艺术作品--目的说明它是在第1,2阶段文档演示的JavaScript面向对象的书写方式的进一步改进,它是现代JavaScript面向对象编程方式(使用基本类来编码)的过渡代码--没有它就没有当今...

    JavaScript高级编程

    一套很适用的JavaScript编程书籍. 主要涵盖的内容: 第1章 JavaScript语言概述 第2章 JavaScript语言基础 第3章 JavaScript事件处理 第4章 JavaScript基于对象编程 第5章 文档对象模型(DOM) 第6章 String、Math、...

    javaScript函数式编程

    JavaScript 是近年来非常受瞩目的一门编程语言,它既支持面向对象编程,也支持函数式编程。本书专门介绍JavaScript函数式编程的特性。 全书共9章,分别介绍了JavaScript函数式编程、一等函数与Applicative编程、变量...

    javascript编程宝典(14-25章光盘素材)

    《JavaScript编程宝典》介绍了JavaScript语言,内容涉及从基础语法到高级技术的方面面面,并通过实例说明如何将这些技术应用到实际开发中。全书共25章,内容包括JavaScript基础语法、支持闭包的函数、基于原型的面向...

    征服RIA:基于JavaScript的Web客户端开发卷二

    JavaScript高级篇:揭示JavaScript的运行机理和高级应用,如面向对象编程、函数式编程和元编程。Ajax篇:Ajax是上帝赐予JavaScript的礼物。凭借着Ajax,JavaScript拥有了异步调度服务端业务逻辑的能力。本篇除介绍...

Global site tag (gtag.js) - Google Analytics