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

JavaScript(二)-- 面向对象

2016-04-03 17:38 411 查看
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,Ford
document.write("<br/>");

var person2 = new Person();
person2.cars.push("Rover");
document.write("person2:");
person2.showPerson();//person1:yuchen的车有:BM,Ford,Rover
document.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,Rover
document.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、对象的继承

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: