javascript学习笔记 (四)-面向对象的实现

javascript中面向对象的实现
javascript中的函数可以充当类的角色,我们用函数的prototype完成类的功能。
首先了解javascript中的对象是如何工作的,对象允许你定义一个变量然后可以在变量上设置任意多的属性
让我们看下一个简单的例子
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> var myObj = new Object;
myObj.a
= 5 ;
myObj['b']
= 10 ;
myObj.c
= 20 ;
myObj.getTotal
= function (){
alert(
this .a + this .b + this .c);
});

// or

var myObj = {a: 5 ,b: 10 ,c: 20 ,getTotal: function (){alert( this .a + this .b + this .c);}};

这两个代码片段创建了相同的变量,myObj。
当你在一个对象中执行一个函数时,"this"指向对象的引用。

javascript中的对象非常有用,我们写一个animal对象
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->
var myAnimal = {
name:'felix',
species:'cat',
talk:
function (){alert('Meow ! ');},
callOver:
function (){alert( this .name + 'ignoresyou');},
pet:
function (){alert('Purr ! ');}
}
现在我们定义了一个变量 myAnimal,名字叫felix。当我们想创建另外一只猫,我们学要键入上述所有代码。于是面向对象思想该起作用了。用一个函数生成类似的对象而不是重复的键入代码。

javascript学习笔记 (四)-面向对象的实现

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> function Cat(name){
this .name = name;

this .species = 'Cat';
this .talk = function (){alert('Meow ! ');}
this .callOver = function (){alert( this .name + 'ignoresyou');},
this .pet = function (){alert('Purr ! ');}
}

var felix = new Cat('Felix');
var sam = new Cat('Sam');
var patty = new Cat('Patty');

felix.pet();
// alerts'Purr!'
sam.callOver(); // alerts'Samignoresyou'.Justlikeacat!
alert(patty.species); // alerts'cat'

上面的例子我们创建了一个函数cat,然后用函数创建了3个新的cat对象:felix,sam和patty。每个cat都有相同的函数:talk,callOver和pet,都有自己的species属性。
我们通常说felix,sam和patty是相同对象的实例。cat函数中的代码是构造函数。接收"name"用来设置this.name。但是在每个 cat构造的时候,我们实际上创建了每个方法的3个副本。由于talk,callOver和pet方法是相同的,我们只需每个方法的一个副本。

我们使用Prototyping重写cat函数
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> function Cat(name){
this .name = name;
}
Cat.prototype.species
= 'Cat';
Cat.prototype.talk
= function (){alert('Meow ! ');};
Cat.prototype.callOver
= function (){alert( this .name + 'ignoresyou');};
Cat.prototype.pet
= function (){alert('Purr ! ');};
javascript学习笔记 (四)-面向对象的实现

上面函数的语法和以前的有些不同。现在可以用Cat.prototype定义属性和方法,而不是在函数体内定义。虽然这样复杂了,但是它提供了很多优点。假设我们给现有的每个cat加一个新的方法sleep 有两种方法:
第一种是跟踪每个cat,给每个cat加入方法。
第二种是使用prototype,我们可以同时为每个cat加入sleep方法
Cat.prototype.sleep = function(){ alert(this.name+' falls asleep'); };
这种方法不但快捷,而且不需要跟踪每个cat去添加sleep方法。
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> function Cat(name){
this .name = name;
}
Cat.prototype
= {
species:'Cat',
talk:
function (){alert('Meow ! ');},
callOver:
function (){alert( this .name + 'ignoresyou');},
pet:
function (){alert('Pet ! ');}
}


需要注意的是使用prototype设置方法会替代以前设置的方法。如果我们通过这种方式添加一个sleep方法
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> Cat.prototype = {
sleep:
function (){alert( this .name + 'fallsasleep');}
}

我们前面的prototypes,species,talk,callOver和pet都将被清除,我们cat的原型方法只有sleep

Prototypes也可以用来扩展javascript内置的对象。我们能实现一个String.prototype.reverse方法

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> String.prototype.reverse = function (){
var out = '';
for ( var i = this .length - 1 ;i >= 0 ;i -- ){
out
+= this .substr(i, 1 );
}
return out;
}
alert('asdf'.reverse());
如果恰当的使用它,将会很有用。
强烈建议不要在array和object中使用prototype,因为这样会影响"for-in"语句的使用。看看下面的例子:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> var myArray = [ 1 , 2 , 3 ];
for (n in myArray)alert(n); // alerts0,1and2-theindexesofthearray.

Array.prototype.something
= function (){};

for (n in myArray)alert(n); // alerts'something',0,1and2.

有其他方法可以达到相同的效果,我个人不喜欢使用prototype扩展array

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> Array.find = function (ary,element){
for ( var i = 0 ;i < ary.length;i ++ ){
if (ary[i] == element){
return i;
}
}
return - 1 ;
}

alert(Array.find(['a','b','c','d','e'],'b'));
// alerts1

如你所见,我们使用Array.find(ary, e)替代ary.find(e),额外的一点代码换来的是不破坏现有javascript的功能性。

Private, Public 和 Static 变量
Private Declared with 'var variableName' or 'function functionName' inside of the object. Can only be accessed by other private or privileged functions.
Public Declared with 'this.variableName' inside of the object. Can be changed by any function or method.
Privileged Declared with 'this.functionName = function(){ ... }' inside of the object. Can be accessed by any function or method and can call reference or change any Private variable.
Prototype Declare with 'Class.prototype.variableName' or 'Class.prototype.functionName'. Functions declared this way will have access to any public or prototype variables. Attempts to change variable created this way will instead create a new public variable on the object and the prototype variable will be unavailable.
Static Declare with 'Class.variableName' or 'Class.functionName'. Can be changed by any function or method. This method is rarely used.

为了理解不同级别,看看下面的例子
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> function Cat(name,color){
/*
Constructor:anycodeinhereisrunwhentheobjectiscreated
*/
Cat.cats
++ ;

/*
Privatevariablesandfunctions-mayonlybeaccessedbyprivateorprivilegedfunctions.

Notethat'name'and'color',passedintotheClass,arealreadyprivatevariables.
*/
var age = 0 ;
var legs = 4 ;
function growOlder(){
age
++ ;
}

/*
Publicvariables-maybeaccessedpubliclyorprivately
*/
this .weight = 1 ;
this .length = 5 ;

/*
Privilegedfunctions-maybeaccessedpubliclyorprivately
MayaccessPrivatevariables.

CanNOTbechanged,onlyreplacedwithpublicversions
*/
this .age = function (){
if (age == 0 ) this .length += 20 ;

growOlder();
this .weight ++ ;
}
}

/*
PrototypedFunctions-maybeaccessedpublicly
*/
Cat.prototype
= {
talk:
function (){alert('Meow ! ');},
callOver:
function (){alert( this .name + 'ignoresyou');},
pet:
function (){alert('Pet ! ');}
}

/*
PrototypedVariables-maybeaccessedpublicly.
Maynotbeoverridden,onlyreplacedwithapublicversion
*/
Cat.prototype.species
= 'Cat';

/*
Staticvariablesandfunctions-maybeaccessedpublicly
*/
Cat.cats
= 0 ;

这里有许多访问限制级别,所有的private,privileged和public函数和变量都会在创建新的实例时被拷贝。通常可以使用prototype和public变量可以完成所有的任务。

你可能感兴趣的:(JavaScript,C++,c,prototype,C#)