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

Javascript面向对象相关知识总结

2013-03-18 22:13 253 查看
“Everything” in JavaScript is an Object.

讨论Javascript肯定离不了上面这句话“在Javascript中一切都是对象”。

Javascript对象和原型

Javascript对象通常有一个构造函数,以及相应的方法和属性。此外,Javascript中的所有对象都继承了Javascript标准Object对象的功能。

在java或c++编程语言中,你可以创建一个从其他类中继承的类,这样它就将继承其父类的功能,并允许覆盖父类的某些功能。与其他编程语言不同,Javascript对象并不遵循传统的面向对象的继承和类的原则, 相反,Javascript对象功能是源于Javascript中的一个特殊概念:原型(prototype)。

Object对象本身并没有什么特别之处,主要是提供了创建新对象的能力。Javascript中通过Object对象提供一个构造函数,从而允许你创建新的对象。这个对象的构造函数能够为对象分配内存,并包含所有属性。Object对象还提供了一个名为prototype的属性,通过它可以扩展任意对象,包括内建对象,如String或Number。prototype属性可以为对象创建新的方法和属性,而这些方法和属性并不是从类中继承的。

例1:

Number.prototype.add = function(val1,val2){ return val1 + val2;};
var num = new Number();
var sum = num.add(8,3);
alert(sum);//sum为11

本例是对内建对象Number进行的扩展。

例2:

var num = new Number();
num.add = function(val1,val2){ return val1 + val2;};
var sum = num.add(8,3);

当通过prototype扩展对象时,扩展的方法和属性将适用于对象的“所有”实例。当扩展对象实例时候,新的方法和属性只适用于该对象实例。

例3:一个完整的程序。本例中使用Object的prototype属性为内建的String对象添加新的方法trim。trim的方法是去除字符串前后的空格。

<script type="text/javascript">
String.prototype.trim = function(){
return (this.replace(/^[\s\xA0]/,"").replace(/[\s\xA0]/,""));
}

window.onload = function(){
var sObj = new String("  This is the String");
document.writeln("--" + sObj + "--" + "<br />");

var sTxt = sObj.trim();
document.writeln("--" + sTxt + "--");
}
</script>

输出为:

-- This is the string --

--This is the string--

基于prototype属性,现在页面中的任何String对象不仅可以调用String对象中的方法和属性,还可以调用新的trim函数。这时你不需要额外创建一个新的对象,而只是扩展了一下现有对象的功能。这也正是基于类和基于原型系统的一大差异。

创建自定义Javascript对象
当创建Javascript自定义对象时,人们通常会使用Javascript函数。当然与普通函数相比,这里使用的函数略有不同,例如函数的写法、私有/公有属性的定义甚至包括属性的封装方法都可能不一样。然而,如果要创建Javascript的自定义对象,就必须从函数开始。
例4:

<script type="text/javascript">
var Tune = function(title){
this.title = title;
var performedBy = new Array();

this.addPerformer = function(performer){
var i = performedBy.length;
performedBy[i] = performer;
}

this.listPerformers = function(){
var singers = "";
for(var i=0; i<performedBy.length; i++){
singers += performedBy[i] + " ";
}
return singers;
}
}

window.onload = function(){
var song = new Tune("Hello");
song.addPerformer("Me");
song.addPerformer("You");
song.addPerformer("Us");
document.writeln("Song is " + song.title);
document.writeln("Performed by " + song.listPerformers());
}
</script>

本例中,我们创建了一个简单的对象Tune,该对象有一个参数title,并赋值给Tune对象的title属性(歌曲标题)。该对象中还有一个数组,通过addPerformer(添加歌手)方法和listPerformers(列出歌手)方法访问。在给页面中,我们通过Object构造函数创建了Tune对象实例,并传入一个字符串参数。接着3次调用addPerformer方法,分别传入3个参数:"Me"、“You”、“Us”;接着调用listPerformers方法,遍历performers数组。该应用程序的功能是将歌曲标题和表演者输出到页面上。

分析:这段代码创建了与对象Tune同名的函数。在Javascript中所有东西都是对象,函数也是对象,所以创建函数,也就是创建了自定义对象。

公有和私有属性

public

this.title

this.addPerformer

this.listPerformer

例4中使用this关键字在对象创建的时候传入参数title,为属性title赋值。这里this关键字是对父对象的引用,也就是新创建对象的实例。this起到的作用是创建一个公有属性,可允许对象以外的访问。例如:document.writeln("Song is " + song.title);

private

var performers

例4中的performers数组并不是通过this关键字直接赋值的,而是由var关键字所创建的变量。

因此所创建的这个变量是对象的私有成员,只限于对象内部访问(包括对象内的方法),而不允许对象外部访问。

例5:创建自定义对象的另一种方法,创建对象实例,并使用对象的prototype为属性和方法进行赋值。

<script type="text/javascript">
function Tune(title){
this.title = title;
}

function printTitle(){
document.writeln(this.title + "<br />");
}

window.onload = function(){
Tune.prototype.print = printTitle;

var oneTune = new Tune("One Title");
oneTune.print();

var anotherTune = new Tune("Another Title");
anotherTune.print();
}
</script>

解释:Javascript中的所有对象都是从Object继承的,所以这些对象都拥有prototype属性,包括自定义对象Tune。本例不是为对象直接添加方法,而是创建一个用来输出歌曲标题的全局函数,然后通过Tune对象的prototype属性将其添加到Tune对象中。

静态属性/方法

static

var newNumber = new Number(34.8896);
document.writeln(newNumber.toExponential(3) + "<br />");
document.writeln(newNumber.toPrecision(3) + "<br />");

显示为:

3.489e+1

34.9

像上例中的toExponential方法和toPrecision方法是基于对象实例newNumber的,而不是基于对象类Number的。

对象方法的另外一种形式是静态方法。静态方法不是基于对象实例的,而是直接为对象类所调用的。所有Math对象的方法都是静态方法。

例: var newNum = Math.abs(oldNum);

同样也适用于属性,静态属性是基于对象本身的,而不是实例。

例如,Number类的5个属性只可以通过Number对象进行访问:

Number.MAX_VALUE Javascript所能表示的最大数值

Number.MIN_VALUE

。。。。

如果用Number实例访问这些属性,那么将会返回undefined

相当于Java语言中用static修饰的方法和属性,但不完全一样。Java中的类的属性可以被实例访问(个人理解)

参考:http://zhidao.baidu.com/question/287582983.html

一个易混淆的地方:

Javascript中只有3种基本数据类型:字符串、数字、布尔值。Javascript还提供了一些内建的对象,如String、Number和Boolean。

这些对象看起来与基本数据类型截然不同,前3种是基本值的类型,后3种则是对象,是拥有内建属性和方法的对象。然而他们又紧密相关。当以对象的方式操作基本类型时,String对象会封装字符串基本类型,而Number和Boolean也同样会封装各自的基本类型。

当在Javascript中创建了简单的字符串变量并使用String对象的属性和方法时,Javascript会隐式地通过String对象封装字符串基本类型,并且调用String对象的属性和方法,最后销毁该对象。

例:

var myName = "Shelley";
alert(myName.strike());
alert(myName.length);

本例中知识创建了一个字符串基本类型的变量myName,然而,当在该变量上调用与String相关的方法及属性时,那么该变量就会被当做是String对象实例。

如果要访问对象的属性,如String对象的length和strike方法,那么可以创建对象变量。如果创建的是字符串基本类型,却又以对象的行为访问,那么Javascript会将该基本类型自动转换成对象,但是转换的String对象只是一个临时变量,并且在属性操作后销毁该对象,所以这种操作不够有效,多了一次转换的过程。

令推荐一篇很不错的译文:JavaScript的public、private和privileged模式
http://hideto.iteye.com/blog/103537
本文出自 “开心菠菜” 博客,请务必保留此出处http://kaixinbocai.blog.51cto.com/3913323/1157523
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: