首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > JavaScript >

javascript对象基础之对象创造

2012-10-31 
javascript对象基础之对象创建看js高级程序一书,记录对自己比较重要的。面向对象语言的要求: 1.封装 2.聚集

javascript对象基础之对象创建

看js高级程序一书,记录对自己比较重要的。

面向对象语言的要求:
1.封装 2.聚集 3.继承 4.多态
1.在Javascript中 可以创建并且使用的对象有三种
(1)本地对象 比如:Array Date and so on。
(2)内置对象 比如:Global Math(每个内置对象都是本地对象)
(3)宿主对象 定义:所有非本地对象都是宿主对象。所以所有的BOM(浏览器对象模型)和DOM(文档对象模型)都是宿主对象。

2.作用域
(1)关键字this:总是指向调用该方法的对象 例如:

var oCar = new Object;oCar.color="red";oCar .showColor = function(){alert(this.color);//outputs "red"};//在上面的环境中 this等于car,下面的代码与上面的代码意义相同var oCar = new Object;oCar.color="red";oCar .showColor = function(){alert(oCar.color);//outputs "red"};

?使用this的好处是:可以在任意多个地方重用同一个函数。

3.定义类或对象

(1)工厂方式:考虑下面的代码

<script type="text/javascript">function createCar(color, doors, mpg) {    var tempcar = new Object;    tempcar.color = color;    tempcar.doors = doors;    tempcar.mpg = mpg;    tempcar.showColor = function () {        alert(this.color)    };    return tempcar;}var car1 = createCar("red", 4, 23);var car2 = createCar("blue", 3, 25);car1.showColor();    //outputs "red"car2.showColor();    //outputs "blue"</script>

?代码够清楚吧 不用多说了,但是要看清楚上面的代码产生的问题:每次调用函数createCar(),都要创建新函数showColor();这意味着每个对象都有自己的showColor()版本,而事实上每个对象都共享了同一个函数。

所有这些问题引发了构造函数方式的出现:考虑下面代码

<script type="text/javascript">function Car(sColor, iDoors, iMpg) {    this.color = sColor;    this.doors = iDoors;    this.mpg = iMpg;    this.showColor = function () {        alert(this.color)    };}var oCar1 = new Car("red", 4, 23);var oCar2 = new Car("blue", 3, 25);oCar1.showColor();    //outputs "red"oCar2.showColor();    //outputs "blue"</script>

你可能已经注意到差别了,在构造函数内部无创建对象,而是使用this关键字。现在就更像创建一般对象了。但是可惜它的缺陷和工厂函数的缺陷一样。

(2)原型方式:即利用prototype属性

首先让我们看下面的例子:

<script type="text/javascript">function Car() {}Car.prototype.color = "red";Car.prototype.doors = 4;Car.prototype.mpg = 23;Car.prototype.showColor = function () {    alert(this.color);};var oCar1 = new Car();var oCar2 = new Car();</script>

在上面的代码中,通过给Car的pototype属性添加属性去定义Car对象的属性。从语义上讲,所有的属性看起来都属于一个对象,从而解决了前面方式存在的问题。但是遗憾的是它并不尽如人意。为什么呢?考虑下面的例子

<script type="text/javascript">function Car() {}Car.prototype.color = "red";Car.prototype.doors = 4;Car.prototype.mpg = 23;Car.prototype.drivers = new Array("Mike", "Sue");Car.prototype.showColor = function () {    alert(this.color);};var oCar1 = new Car();var oCar2 = new Car();oCar1.drivers.push("Matt");alert(oCar1.drivers);    //outputs "Mike,Sue,Matt"alert(oCar2.drivers);    //outputs "Mike,Sue,Matt"</script>

看到了吧 这是因为Car的两个实例都指向同一个数组。所以输出都一样了。

那么是否有一种合理的创建对象的方法呢?答案是需要联合使用构造函数和原型方试? 考虑下面的列子

<script type="text/javascript">function Car(sColor, iDoors, iMpg) {    this.color = sColor;    this.doors = iDoors;    this.mpg = iMpg;    this.drivers = new Array("Mike", "Sue");}Car.prototype.showColor = function () {    alert(this.color);};var oCar1 = new Car("red", 4, 23);var oCar2 = new Car("blue", 3, 25);oCar1.drivers.push("Matt");alert(oCar1.drivers);    //outputs "Mike,Sue,Matt"alert(oCar2.drivers);    //outputs "Mike,Sue"</script>
?根据上面讲述的内容 不难看出这种方式创建对象就更像创建一般对象了。这才是最优的

(3)其他方法?

包括动态原型法(和上面最优的方式其实差不多,不做介绍了) 和混合工厂方式(不推荐,不做介绍了)

4.采用哪种方式:不用多说 当然是最优的拉,给个例子。运行下就知道效率了

<script type="text/javascript">function StringBuffer() {    this.__strings__ = new Array;}StringBuffer.prototype.append = function (str) {    this.__strings__.push(str);};StringBuffer.prototype.toString = function () {    return this.__strings__.join("");};var d1 = new Date();var str = "";for (var i=0; i < 10000; i++) {    str += "text";}var d2 = new Date();document.write("Concatenation with plus: " + (d2.getTime() - d1.getTime()) + " milliseconds");var buffer = new StringBuffer();d1 = new Date();for (var i=0; i < 10000; i++) {    buffer.append("text");}var result = buffer.toString();d2 = new Date();document.write("<br />Concatenation with StringBuffer: " + (d2.getTime() - 
d1.getTime()) + " milliseconds");</script>
?这段代码对字符串链接进行2个测试,第一个使用加号,第二个使用StringBuffer类。事实证明后者比前者节省大量的时间。COOL! OVER!

?

?

?

?

?

?

?

?

?

热点排行