您的位置:首页 > Web前端 > JavaScript

[转]翻译:有点高级的JavaScript面向对象特征指南快速教程

2009-09-24 18:13 567 查看
翻译:有点高级的JavaScript面向对象特征指南快速教程,呵呵

翻译说明:本文是我从Prado框架的《快速入门指南》翻译中摘录出来的,感觉对JavaScript的学习很有帮助,特贴出备忘。

Javascript简介

本指引基于Sergio Pereira的 Quick guide to somewhat advanced JavaScript tour of some OO features。

嘿,我不知道你能那样做

如果你是一个Web开发者而且与我来自同一个地方,你也许在你的Web页面中使用过相当多的Javascript,大部分用来作用户界面(UI)的粘合。

直到现在,我才知道Javascript具有比我过去使用的更多的面向对象能力,只是我没有如我所需的去使用它。当浏览器开始支持更标准的
Javascript和DOM的功能集时,要为客户端上的运行而编写更复杂和多功能的代码就变得可行了。它助长了AJAX现象的产生。

当我们都开始学习它适合编写什么酷的AJAX应用时,我们开始关注到我们过去知道的Javascript不过只是冰山一角而已。我们现在知道
Javascript不仅仅被用于象输入校验等简单的用户界面杂务和其他琐碎任务。现在的客户端代码更高级和分层,更象一个真正的桌面应用或一个客户端-
服务器的富客户端。我们在其中看到了过去仅在服务器端的代码中见到的类库、对象模型、继承关系、模式和许多其他的东西。

突然在我们能讲到的许多方面被放到了比以前更高的位置。要为新的Web编写应用,我们必需提高我们的Javascript水平来跟上它而且要更加熟
练。假如你尝试运用许多现有的javascript库,如:Prototype.js、Scriptaculous、moo.fx、Behaviour、
YUI等,你最终会发现自己要阅读JS代码。或许因为你想要学习它们如何实现,或因为你的好奇,或通常因为那是知道如何使用它的唯一办法,大多数这些库象
是不太注重文档。无论个案会是什么,假如你之前不了解那样的东西,你将要面对一些引起恐慌的外部技术。

本文的目的正好是解说许多我们还不熟悉的构造类型。

JSON (JavaScript Object Notation-Javascript对象表示法)

Javascript对象表示法(JSON),是围绕AJAX主题突然出现的一个新的时髦词。JSON,简单的说就是一种在Javascript中定义对象的方法。让我们马上来看看一个实例并体会它如何简单。

var myPet = { color: 'black', leg_count: 4, communicate: function(repeatCount){

for(i=0;i<repeatCount;i++) alert('Woof!');} };

就让我们加入些许格式让它看起来象我们平常所认识的那样:

var myPet =

{

color: 'black',

legCount: 4,

communicate: function(repeatCount)

{

for(i=0;i<repeatCount;i++)

alert('Woof!');

}

};

在这我们创建了一个带两个属性(color和legCount)和一个方法(communicate)的对象引用。不难发现,该对象的属性和方法用一个逗
号区隔的列表来定义。每个成员通过名称来引入,接着是冒号和定义。对于属性来说很容易,仅仅是属性值。方法通过指派一个匿名函数来创建,我们下面会更好地
说明。在该对象被创建并指派给变量myPet之后,我们可以如下使用它:

alert('my pet is ' + myPet.color);

alert('my pet has ' + myPet.legCount + ' legs');

//if you are a dog, bark three times:

myPet.communicate(3);

You'll see JSON used pretty much everywhere in JS these days, as
arguments to functions, as return values, as server responses (in
strings,) etc.

你想说什么?函数也是一个对象?

对于开发者来说这可能与众不同,但在JS中一个函数也是一个对象。你可以象参数一样把一个函数传送给另一个函数,就象你可以传送一个字符串一样。这些被广泛应用而且非常便利。

看看这个实例。我们将把函数传送到另一个使用它们的函数去。

var myDog =

{

bark: function()

{

alert('Woof!');

}

};

var myCat =

{

meow: function()

{

alert('I am a lazy cat. I will not meow for you.');

}

};

function annoyThePet(petFunction)

{

//let's see what the pet can do

petFunction();

}

//annoy the dog:

annoyThePet(myDog.bark);

//annoy the cat:

annoyThePet(myCat.meow);

注意,我们把没有添加"()"的myDog.bark和myCat.meow传送给它们。假如我们那样做了,我们不是传送函数,而是调用那些方法并传送它们的返回值,这里的两个个案中都未定义。

要是你想另我的懒猫起来嗥叫,你可以简单地这样做:

myCat.meow = myDog.bark;

myCat.meow(); //alerts 'Woof!'

数组、项目和对象成员

在JS中下列两行做了同样的事。

var a = new Array();

var b = [];

正如我确定你已经知道的那样,你可以通过使用方括号在一个数组中访问个别项目:

var a = ['first', 'second', 'third'];

var v1 = a[0];

var v2 = a[1];

var v3 = a[2];

但你还不限于数字索引。你可以通过使用它的名字以字符串来访问一个JS对象的任何成员。下面的例子创建了一个空对象,并通过名字加入了一些成员。

var obj = {}; //new, empty object

obj['member_1'] = 'this is the member value';

obj['flag_2'] = false;

obj['some_function'] = function(){ /* do something */};

上述代码的作用与下面的相同:

var obj =

{

member_1:'this is the member value',

flag_2: false,

some_function: function(){ /* do something */}

};

在许多情形下,在JS中对象的概念和关联的数组(杂凑)没有区别。下面两行代码都做了同样的事情。

obj.some_function();

obj['some_function']();

关于对象已经够了,我现在能有一个类了吗?

面向对象编程语言的巨大力量来源于类的使用。我不认为仅应用我之前使用其他语言的经验就能推测出在JS中如何定义类。这由你自己来判断。

//defining a new class called Pet

var Pet = function(petName, age)

{

this.name = petName;

this.age = age;

};

//let's create an object of the Pet class

var famousDog = new Pet('Santa/'s Little Helper', 15);

alert('This pet is called ' + famousDog.name);

让我们看看如何加入一个方法到我们的Pet类。我们将使用所有类都具有的prototype属性。prototype属性是一个包含任何对象的类会具有的
所有成员的对象。甚至默认的JS类,如String、Number和Date拥有一个的prototype对象,它能让我们可以添加方法和属性并使那个类
的任何对象自动获取这个新成员。

Pet.prototype.communicate = function()

{

alert('I do not know what I should say, but my name is ' + this.name);

};

那就是一个类似于prototype.js的库会派上用场的时候。如果我们使用prototype.js,我们能使我们的代码看起来更清晰(至少在我看来是这样)。

var Pet = Class.create();

Pet.prototype =

{

//our 'constructor'

initialize: function(petName, age)

{

this.name = petName;

this.age = age;

},

communicate: function()

{

alert('I do not know what I should say, but my name is ' + this.name);

}

};

函数作为参数,一个有趣的模式

假如你从来没有接触过支持闭合的语言,你也许会发现下面的惯用法太令人震惊了。

var myArray = ['first', 'second', 'third'];

myArray.each( function(item, index)

{

alert('The item in the position #' + index + ' is:' + item);

});

哇!在你断定我已经离题太远并且想转去比这篇更好点的文章之前,让我们在这解释一下要继续干些什么。

首先,在上述实例中我们使用了prototype.js库,它添加了each函数到Array类。该each函数接到一个函数对象的参数。这个函数
对于数组中的每个项目都将被依次调用一次,对于当前项目调用时传送两个参数,item和index。让我们称这个函数为iterator函数。我们也能象
这样编写代码:

function myIterator(item, index)

{

alert('The item in the position #' + index + ' is:' + item);

}

var myArray = ['first', 'second', 'third'];

myArray.each( myIterator );

我们不会象那些学校里的那些天真孩子那样做的,对吧?虽然更严格地说,后面的形式更易于理解但导致我们要进入代码中四处找寻myIterator函数。最
好在它调用的同一个地方那里有迭代函数的逻辑。在本案例中,我们也不会在其他任何地方需要迭代函数,所以我们无损地把它转化成一个匿名函数。

这是this,但有时this也是那个

当使用JS开始编写我们的代码时,我们最普遍的一个麻烦就是this关键字的使用。它是一个真正的牵绊。

就象我们之前提及的那样,在JS中一个函数也是一个对象,而且有时候我们不注意我们正在传出一个函数。

拿这小段代码举个例:

function buttonClicked()

{

alert('button ' + this.id + ' was clicked');

}

var myButton = document.getElementById('someButtonID');

var myButton2 = document.getElementById('someOtherButtonID');

myButton.onclick = buttonClicked;

myButton2.onclick = buttonClicked;

由于buttonClicked函数在任何对象之外被定义,我们也许以为this关键字会包含一个window或document对象(假设这些代码位于一个在浏览器中被浏览的HTML页面中间)的引用。

但是当我们运行这段代码时,我们看到它如愿工作并显示被点击按钮的id。究竟其中发生了什么另我们使每个按钮的onclick方法包含buttonClicked对象引用,而无论之前那里有什么。现在无论按钮什么时候被点击,浏览器都会运行一些类似下行的东西:

myButton.onclick();

那毕竟不是这么混乱,是吧?只要你了解有别的对象要进行处理并想在这些对象的事件上,如点击按钮,进行什么行动后发生了什么就行了。

var myHelper =

{

formFields: [ ],

emptyAllFields: function()

{

for(i=0; i < this.formFields.length; i++)

{

var elementID = this.formFields[i];

var field = document.getElementById(elementID);

field.value = '';

}

}

};

//tell which form fields we want to work with

myHelper.formFields.push('txtName');

myHelper.formFields.push('txtEmail');

myHelper.formFields.push('txtAddress');

//clearing the text boxes:

myHelper.emptyAllFields();

var clearButton = document.getElementById('btnClear');

clearButton.onclick = myHelper.emptyAllFields;

因此你想:好了,现在我可以在我的页面上点击Clear按钮,那三个文本框就将被清空。然后你尝试点击该按钮后仅得到一个运行时错误。该错误将涉及(猜猜
是什么?)this关键字。该问题是this.formFields没被定义即便this包含了一个到按钮的引用,那正是现在所发生的。一个快速的解决方
案是重写我们最后一行的代码。

clearButton.onclick = function()

{

myHelper.emptyAllFields();

};

我们创建一个全新的函数,那种方法在协助对象的场景中调用了我们的协助方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: