JavaScript(二)-- 面向对象

来源:互联网 发布:吸烟罚款 知乎 编辑:程序博客网 时间:2024/06/04 17:22

JavaScript也是面向对象的编程思想,本文讲解如何创建JavaScript的对象,以及对象的继承等机制。

1、创建对象


1.原始方法new Object()

  <html><head><meta charset="utf-8"/><script type="text/javascript">//如果构造方法为无参的,可以去除(),直接new Object;personObj = new Object;personObj.firstname="yuchen";personObj.lastname="wu";personObj.age=25;personObj.eyecolor="black";personObj.show=function (){document.write(this.firstname+" "+this.lastname+"的年龄是:"+this.age+"岁!");}//直接使用对象的属性document.write(personObj.firstname+"的年龄是:"+personObj.age+"岁。");//调用对象的方法personObj.show();</script></head><body></body></html>

可以使用工厂方法,在创建多个对象的时候使用:

<script type="text/javascript">function createPerson(firstname,lastname,age,eyecolor){//工厂方法的第一步就是使用new Object()创建对象,然后对属性进行赋值person = new Object();person.firstname=firstname;person.lastname=lastname;person.age=age;person.eyecolor=eyecolor;person.show = function (){//一般需要指明this.属性,不使用this也没错document.write(this.firstname+"的年龄是:"+this.age+"岁!");}return person;}person1=createPerson("yuchen","wu" , 25,"black");person1.show();person2=createPerson("jack","SR",32,"blue");person2.show();</script>
在对方法进行定义时,出现每个对象都需要定义一次方法的情况,实际上只需要所有对象共享一个同名方法就可以,所以,改进是

在对象定义体外定义函数,在定义对象属性时,把函数引用赋给方法属性。

<script type="text/javascript">function personshow(){//一般需要指明this.属性,不使用this也没错document.write(this.firstname+"的年龄是:"+this.age+"岁!");}function createPerson(firstname,lastname,age,eyecolor){//工厂方法的第一步就是使用new Object()创建对象,然后对属性进行赋值person = new Object();person.firstname=firstname;person.lastname=lastname;person.age=age;person.eyecolor=eyecolor;//****把函数引用赋给对象属性,函数的定义在对象定义前后都可以person.show = personshow;return person;}person1=createPerson("yuchen","wu" , 25,"black");person1.show();person2=createPerson("jack","SR",32,"blue");person2.show();</script>
这样就解决了重复定义函数的问题,然而这样看起来,函数就不像对象的方法。

构造函数创建对象也存在这样的问题,这就体现了原型方法的优势。

2.使用构造函数

构造函数定义时,首字母为小写也可用,但一般写为大写。
<script type="text/javascript">function Person(firstname,lastname,age,eyecolor){this.firstname=firstname;this.lastname=lastname;this.age=age;this.eyecolor=eyecolor;this.show = function (){//一般需要指明this.属性,不使用this也没错document.write(this.firstname+"的年龄是:"+age+"岁!");}}person1=new Person("yuchen","wu" , 25,"black");person1.show();person2=new Person("jack","SR",32,"blue");person2.show();</script>

3、原型方式

原型方式就是使用对象的prototype属性,将对象属性和方法都赋给prototype,这是属性可以看做对象的基因,通过该属性就可以确定对象。

首先,定义对象的无参构造函数

然后,使用对象的prototype属性

<script type="text/javascript">function Person(){}Person.prototype.firstname = "yuchen";Person.prototype.age = 26;Person.prototype.showPerson = function (){document.write(this.firstname+"的年龄是:"+this.age+"岁");}var person1=new Person();person1.showPerson();document.write("<br/>")var person2=new Person();person2.showPerson();</script>
这种方法,避免了每个对象都定义方法的弊端,因为是通过prototype将属性与函数的引用关联起来的。而且从语义上看,就能明白所有属性都属于同类对象。

使用原型还可以判断,变量是否指向某一特定对象。

使用 变量 instanceof 对象的方式,返true或false

<script type="text/javascript">function Person(){}Person.prototype.firstname = "yuchen";Person.prototype.age = 26;Person.prototype.showPerson = function (){document.write(this.firstname+"的年龄是:"+this.age+"岁");}var person1=new Person();document.write(person1 instanceof Person);//true</script>

但是,使用原型方式创建对象,也有弊端:

1)只有无参构造函数,不能在创建对象的时候初始化属性,只能创建好对象后,改变属性值,麻烦

2)使用对象,目的是函数被不同对象变量共享,但是也导致了属性为引用对象的共享,比如属性= new Array(),那么该属性就是被多个对象变量共享的:

<script type="text/javascript">function Person(){}Person.prototype.firstname = "yuchen";Person.prototype.age = 26;Person.prototype.cars = new Array("BM","Ford");Person.prototype.showPerson = function (){document.write(this.firstname+"的车有:"+this.cars);}var person1=new Person();person1.showPerson();//yuchen的车有:BM,Forddocument.write("<br/>");var person2 = new Person();person2.cars.push("Rover");document.write("person2:");person2.showPerson();//person1:yuchen的车有:BM,Ford,Roverdocument.write("<br/>");document.write("person1:");person1.showPerson();//person1:yuchen的车有:BM,Ford,Rover</script>
造成了引用对象属性的共享,所以引出混合的“构造函数\原型方式”

4、混合的构造函数 原型方式

思想就是,在创建对象中,使用构造函数为对象的属性赋值;使用原型方式为方法属性赋值。

<script type="text/javascript">function Person(firstname, age){this.firstname = firstname;this.age = age;this.cars = new Array("BM","Ford");}Person.prototype.show = function (){document.write(this.firstname+"的车有:"+this.cars);}person1 = new Person("yuchen", 25);person1.cars.push("Rover");person1.show();//yuchen的车有:BM,Ford,Roverdocument.write("<br/>");person2 = new Person("jack",32);person2.cars.push("Benz");person2.show();//jack的车有:BM,Ford,Benz</script>
但是这样的定义方式,与传统意义上的对象封装,把属性和方法都放在类体中不同,纵然人感觉不严格,所以就有了动态原型方法。

5、动态原型方法

动态原型方法的思想,就是在对象中添加一个属性,用以标示判断原型中的方法是否定义过,如果定义过就不许再定义。

<script type="text/javascript">function Person(firstname, age){this.firstname = firstname;this.age = age;this.cars = new Array("BM","Ford");//typeof为一元运算符,对Person._initialized进行操作后再与后边"undefined"比较//typeof判断变量的类型,返回Boolean,String等字符串,如果变量没有定义过,返回"undefined"if(typeof Person._initialized == "undefined"){Person.prototype.show = function(){document.write(this.firstname+"的车有:"+this.cars);};Person._initialized = true;}}p1 = new Person("yuchen",25);p1.cars.push("Rover");p1.show();document.write("<br/>")p2 = new Person("jack",32);p2.cars.push("Benz");p2.show();</script>
这样定义对象的过程,在语句结构上来看,就很符合面向对象的思想模型了。其中_initialized是一个属性变量,可以改为别的名字,只是用来进行判断的。

介绍了五种创建对象的方法,其中最经常使用的是:混合构造函数/原型方式、和动态原型方式,两者其实等价。

2、修改对象

对象的修改,一般都是通过对象的prototype进行修改。

1.为已有对象创建新的方法

例1:
Number的toString方法,向其传入数值16,8等数字,就会返回指定数值的进制数字符串
现在为Number对象添加toHexString()方法,直接返回数值的十六进制数
<script type="text/javascript">Number.prototype.toHexString = function(){return this.toString(16);}var iNum = 15;alert(iNum.toHexString());//f</script>
例2:为Array添加indexOf方法,如图String的indexOf方法一样,返回指定值的下标
<script type="text/javascript">Array.prototype.indexOf = function(val){for(var i=0;i<this.length;i++){if(this[i] == val){return i;}}return -1;}var arr = new Array(1,2,4,5,7,11);alert(arr.indexOf(7));//4</script>

2、为所有本地对象添加方法

上小节是为单个的已存在对象添加方法,那么为本地所有的对象添加方法,其实就是通过对Object对象添加方法
因为每个对象都继承自Object对象,所以每个新建的对象就有了这个添加的方法。
<script type="text/javascript">Object.prototype.showValue = function(){//valueOf()返回对象的原始值alert(this.valueOf());};var str = "mylove";var iNum = 32;str.showValue();iNum.showValue();</script>

3、重定义已有的方法

其实就是新添加的函数与原有存在的方法同名,覆盖了以前的方法。
<script type="text/javascript">Array.prototype.push = function(){alert("aaaa");}var arr = new Array();arr.push();//会弹出警告框aaaa</script>

4、极晚绑定

即,先实例化变量,在对对象添加新的方法,在先前定义变量中,同样适用,但一般不这样使用,因为不方便查看与梳理
<script type="text/javascript">var arr = new Array();Array.prototype.push = function(){alert("aaaa");}arr.push();//会弹出警告框aaaa</script>

3、对象的继承




0 0
原创粉丝点击