高级面向对象 之 js是基于原型的程序

来源:互联网 发布:经典网络仙侠文 编辑:程序博客网 时间:2024/06/05 22:39

1.简单的面向对象的应用


 
  下面是一个最基本的面向对象的写法(有属性,有方法,还有它如何创建的)
 
  1.首先写个一构造函数,在构造函数里面添加属性
  2.将方法定义到构造方法的原型(prototype)上(这样的好处是:通过该构造函数生成的实例所拥有的方法都是指向一个函数的索引,这样可以节省内存,提高性能)

function Aaa(){
this.name = "张三";
}

Aaa.prototype.showName = function(){
alert(this.name);
}

var a1 = new Aaa();
a1.name;
a1.showName();
创建一个对象a1,这样对象a1就拥有了name属性和showName方法,这是一个最简答的面向对象的应用。

2.js是基于原型的程序理解


我们在写面向对象程序的时候,究竟是为了什么呢?能够拥有像系统对象那样的功能,如数组时间对象那样,
可以直接通过对象调用方法

var arr = new Array();
arr.push();
arr.sort();
我们可以发现系统对象Array的使用跟我们写的面向对象的使用(上例子中的Aaa)好像是特别类似,也是通过一个构造函数的
形式来创建一个对象,这个对象拥有属性和方法。其实在JS源码当中,系统对象也是基于原型的程序。
那我们可以想象出来在js源码当中数组对象是怎么设计的(会有一个Array构造函数,
构造函数里面有他相关的的属性,然后将方法定义在构造函数的原型上.)

function Array(){
this.length=0;
}

Array.prototype.push=function(){};
Array.prototype.sort=function(){};
所以当我们了解了系统对象内部的结构后,我们在写面向对象的时候就需要特别小心,千万不要去修改或添加系统对象的属性和方法
,不然可能会影响该系统对象的属性和方法的使用

既然我们找到了js就是一个基于原型的程序下面我们来看个例子:

var arr = [1,2,3];
arr.push(4,5,6);
alert(arr);

如我们定义一个数组,数组的length为3,value值为1,2,3 然后我们调用系统对象Array的push方法给数组arr添加3个值4,5,6
然后我们alert这个数组arr发现它的值变为[1,2,3,4,5,6],可以正常使用.
接下来我们在push方法的前面添加下面这段代码
Array.prototype.push=function(){}; 这段代码将Array对象的原型方法push指向一个空的函数
再执行上面的alert(arr)我们会发现弹出的值为[1,2,3]。4,5,6并没有添加成功.这是因为我们重写了数组对象的原型方法push.
数组对象Array的原型方法push被覆盖掉了,这也恰好说明了js是基于原型的程序.因此我们尽量不要去修改或者添加系统对象的
属性或者方法.(如果被我们修改了,其他人使用该方法或属性的时候,可能就会失效了)

当然我们也可以通过原生的js实现数组对象的push 方法,代码如下:

var arr = [1,2,3];
Array.prototype.push = function() {
// this: 1,2,3  谁调用这个方法 this就指向谁,这里的this 指向arr
// arguments:4,5,6

for(var i =0;i<arguments.length;i++){
this[this.length]=arguments[i];
}

// 原声Array对象的push方法会返回 数组的长度,我们这里也返回一下
return this.length;
};

arr.push(4,5,6);
alert(arr);
我们会发现得到的结果跟我们直接调用系统对象Array的push方法得到的结果一样.

总结: 如果有兴趣,我们其实可以把系统对象如数组,时间等的方法自己写一下,一是可以锻炼我们面向对象的写法,
二是可以我们逻辑,和技术的语法掌握都有很大的帮助.