购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.10 JavaScript中的面向对象

面向对象是一种新兴的程序设计方法,一种新的程序设计规范,其基本思想是使用对象、类、继承、封装、消息等基本概念来进行程序设计。从现实世界中客观存在的事物(即对象)出发来构造软件系统,并且在系统构造中尽可能运用人类的自然思维方式。

面向对象最重要的两个概念就是对象和类。

对象是系统中用来描述客观事物的一个实体,它是构成系统的一个基本单位。一个对象由一组属性和对这组属性进行操作的一组函数组成。

类是具有相同属性和函数的一组对象的集合,它为属于该类的所有对象提供了统一的抽象描述,其内部包括属性和函数两个主要部分。但是需要注意的是,JavaScript语言中并没有提供类的定义能力,只能直接创建对象。

2.10.1 创建对象

在JavaScript语言中虽然不能定义类,但可以直接创建对象,面向对象的效果是一样的。JavaScript语言中创建对象代码的写法与其他常见语言(如Java、C#和C++等)完全不同,有多种函数可以创建JavaScript中的对象。下面分别介绍一下。

1.使用字面量创建对象

JavaScript中的对象与数值、字符串等类似,都属于基本数据类型,它们可以使用字面量来表示。对象字面量类似于JSON 对象,采用对象字面量表示的JavaScript对象是一个无序的“名称,值”对集合,一个对象以“{”(左括号)开始,“}”(右括号)结束。每个“名称”后跟一个“:”(冒号),“名称,值”对之间使用“,”(逗号)分隔,语法如图2-11所示。

图2-11 JavaScript对象字面量表示语法结构图

字面量的每一个“名称,值”对就是对象的一个属性。

实例代码如下:

    var Person={                ①
        name:"Tony",           ②
        age :18,                ③
        description :function() {    ④
            var rs=this.name + "的年龄是:" +this.age;    ⑤
            return rs;        
        }
    }
    
    var p=Person;            ⑥
    console.log(p.description());    ⑦

上述代码创建了Person对象,其中第①行代码是声明对象名为Person,第②行代码是定义Person对象的name属性,第③行代码是定义Person对象的age属性,它们都采用“名称,值”对方式。第④行代码很特殊,它是定义对象的description函数,也是采用“名称/值”对结构,但是“值”部分是一个函数。第⑤行代码是访问对象的name和age属性,需要使用this关键字,this关键字指代当前对象。第⑥行代码var p=Person是将Person对象赋值给p变量,这时p和Person是同一个东西。第⑦行代码调用Person对象description()函数。

2.使用Object.create()函数创建对象

可以使用Object.create()函数,它的优势在于能够在原来对象基础上复制出一个新的对象。

实例代码如下:

    var Person={                ①
        name:"Tony",
        age:18,
        description:function () {
            var rs=this.name + "的年龄是:" + this.age;
            return rs;
        }
    }
    
    var p=Person;
    console.log(p.description());
    
    var p1=Object.create({    ②
        name:"Tom",
        age:28,
        description:function () {
            var rs=this.name + "的年龄是:" + this.age;
            return rs;
        }
    });
    console.log(p1.description());
    
    
    var p2=Object.create(Person);                        ③
    p2.age=29;                ④
    console.log(p2.description());
    
    console.log(Person.description());                        ⑤

运行结果如下:

    Tony的年龄是:18
    Tom的年龄是:28
    Tony的年龄是:29
    Tony的年龄是:18

上述代码第①行创建对象Person,第②行和第③行代码都是通过Object.create()函数创建对象。但是第②行Object.create()函数的参数还是采用对象字面量标识。第③行的Object.create()函数的参数Person对象相当于赋值了Person对象,而且是“深层复制”,但在第④行修改p2对象的age属性后,不会对Person对象产生任何影响,所以在第⑤行代码打印Person对象的内容时仍然是“Tony的年龄是:18”。

3.使用函数对象

还可以通过构造函数创建对象。实例代码如下:

    function Student(name, age) {  ①
        this.name=name;    ②
        this.age=age;        ③
        this.description=function () {                        ④
            var rs=this.name + "的年龄是:" + this.age;            ⑤
            return rs;
        }
    }
    
    var p3=new Student('Tony', 28);                        ⑥
    var p4=new Student('Tom', 38);                        ⑦
    console.log(p3.description());
    console.log(p4.description());

上述代码第①行是声明构造函数,构造函数可以初始化对象属性,其中name和age是构造函数的参数。第②行代码this.name=name是通过name参数初始化name属性,第③行代码this.age=age是通过age参数初始化age属性。第④行代码很特殊,它是定义对象的description函数,第⑤行代码是访问对象的name和age属性,需要使用this关键字,this关键字指代当前对象。第⑥行和第⑦行代码是创建Student对象p3和p4,p3和p4是两个不同的对象。

2.10.2 常用内置对象

在JavaScript中有一些常用的内置对象,它们包括Object、Array、Boolean、Number、String、Math、Date、RegExp和Error。

下面分别介绍Object、String、Math和Date等类的使用。

1.Object对象

Object对象是所有JavaScript对象的根,每一个对象都继承于Object对象。实例代码如下:

    var o=new Object();    ①
    
    console.log(o.toString());  ②
    console.log(o.constructor);  ③
    console.log(o.valueOf());   ④

运行结果如下:

    [object Object]
    [Function:Object]
    {}

上述代码第①行是创建Object对象,第②行代码是调用Object对象的toString()函数,该函数返回描述对象的字符串。第③行代码是调用Object对象的constructor属性,可以返回对象的构造函数。第④行代码是调用Object对象的valueOf()函数,可以返回对象的对应值。

2.String对象

String是字符串对象,String对象有很多常用函数。实例代码如下:

    var s=new String("Tony Guan");                        ①
    console.log(s.length);                               //9        ②
    console.log(s.toUpperCase());                       //TONY GUAN   ③
    console.log(s.toLowerCase());                       //tony guan    ④
    
    console.log(s.charAt(0));                           //T        ⑤
    console.log(s.indexOf('n'));                           //2        ⑥
    console.log(s.lastIndexOf('n'));                    //8        ⑦
    
    console.log(s.substring(5, 9));                     //Guan      ⑧
    console.log(s.split(" "));                //[ 'Tony', 'Guan' ]  ⑨

上述代码第①行是创建String对象,第②行代码调用String对象的length属性,属性length是获得字符串的长度。第③行代码调用String对象的toUpperCase()函数,它将字符串中的字符转换为大写。第④行代码调用String对象的toLowerCase()函数,它将字符串中的字符转换为小写。第⑤行代码调用String对象的charAt(index)函数,获得字符串index索引位置的字符。第⑥行代码调用String对象的indexOf('n')函数,从前面查找字符串中字符串n所在的位置。第⑦行代码调用String对象的lastIndexOf('n')函数,从后面查找字符串中字符串n所在的位置。第⑧行代码调用String对象的substring(5, 9)函数,截取子字符串5为开始位置,9为结束位置。第⑨行代码调用String对象的split(" ")函数,指定字符分割字符串,返回值是数组类型。

3.Math对象

Math对象是与数学计算有关系的对象。实例代码如下:

    console.log(Math.PI);     ①
    console.log(Math.SQRT2);   ②
    console.log(Math.random());  ③
    
    console.log(Math.min(1,2,3));  ④
    console.log(Math.max(1,2,3));  ⑤
    
    console.log(Math.pow(2, 3));   ⑥
    console.log(Math.sqrt(9));   ⑦

上述代码第①行Math.PI是获得圆周率常量,第②行代码Math.SQRT2是2的平方根,第③行代码Math.random()是获得0~1之间随机数,第④行代码是获得集合中的最小值,第⑤行代码是获得集合中的最大值。第⑥行代码Math.pow(2, 3)是计算2的3次幂。第⑦行代码Math.sqrt(9)是计算9的平方根。

4.Date对象

Date是日期对象。实例代码如下:

    var d=new Date();        ①
    console.log(d.toString());②
    
    var d=new Date('2009 11 12');    ③
    console.log(d.toString());
    
    var d=new Date('1 2 2012');  ④
    console.log(d.toString());
    console.log(d.getYear());                   //112                ⑤
    console.log(d.getMonth());              //0                ⑥
    console.log(d.getDay());                 //1                ⑦

运行结果如下:

    Sat Aug 30 2014 15:06:44 GMT+0800 (中国标准时间)
    Thu Nov 12 2009 00:00:00 GMT+0800 (中国标准时间)
    Mon Jan 02 2012 00:00:00 GMT+0800 (中国标准时间)
    112
    0
    1

上述代码第①、③和④行创建Date对象,它们提供了不同的构造函数,其中第①行构造函数是空的,它能够获得当前系统时间;第③行代码的构造函数是通过年、月、日创建对象;第④行代码的构造函数是通过月、日、年格式创建对象。第②行代码通过toString()函数输出对象的描述信息,这些信息是对象日期相关信息。第⑤行代码通过getYear()函数获得日期对象的“年”信息,这个“年”是需要+1900才是习惯的表示方式。第⑥行代码通过getMonth()函数获得日期对象的“月”信息,这个“月”需要+1才是习惯的表示方式。第⑦行代码通过getDay()函数获得日期对象的“星期”信息,如果是星期日,getDay()函数返回0;如果是星期一,getDay()函数返回1。依此类推,星期六返回6。

2.10.3 原型

每一个JavaScript对象都是从一个原型继承而来的,可以通过它的prototype属性获得该原型对象。JavaScript对象继承机制建立在原型模型基础之上。

下面通过矢量对象介绍一下原型的使用,我们知道,在物理学中矢量是有方向和大小的,因此需要两个属性分别表示大小和方向。矢量Vector对象代码如下:

    function Vector(v1, v2) {    ①
        this.vec1=v1;        ②
        this.vec2=v2;        ③
    
        this.add=function (vector) {    ④
            this.vec1=this.vec1 + vector.vec1;                ⑤
            this.vec2=this.vec2 + vector.vec2;                ⑥
        }
    
        this.toString=function () {⑦
            console.log("vec1=" + this.vec1 + ", vec2=" + this.vec2);
        }
    }
    
    
    var vecA=new Vector(10.5, 4.7);
    var vecB=new Vector(32.2, 47);
    //vecA=vecA + vecB 赋值给vecA
    vecA.add(vecB);
    vecA.toString();

运行结果如下:

    vec1=42.7, vec2=51.7

上述代码第①行声明Vector矢量对象,代码第②行和第③行定义的vec1和vec2属性分别代表矢量的大小和方向属性。第④行代码定义两个矢量相加函数,第⑤行代码是两个矢量的vec1属性相加,第⑥行代码是两个矢量的vec2属性相加。第⑦行代码是定义打印矢量内容函数。

随着需要的变化,还需要矢量相减函数,可以使用原型扩展矢量相减功能。实例代码如下:

    function Vector(v1, v2) {
        this.vec1=v1;
        this.vec2=v2;
    
        this.add=function (vector) {
            this.vec1=this.vec1 + vector.vec1;
            this.vec2=this.vec2 + vector.vec2;
        }
    
        this.toString=function () {
            console.log("vec1=" + this.vec1 + ", vec2=" + this.vec2);
        }
    }
    
    Vector.prototype.sub=  function (vector) {                ①
        this.vec1=this.vec1 - vector.vec1;②
        this.vec2=this.vec2 - vector.vec2;③
    }
    
    var vecA=new Vector(10.5, 4.7);
    var vecB=new Vector(32.2, 47);
    vecA.sub(vecB);
    vecA.toString();

运行结果如下:

    vec1=-21.700000000000003, vec2=-42.3

上述代码第①行是增加sub(矢量相减)函数,Vector.prototype是矢量对象的原型属性。第②行代码是两个矢量的vec1属性相减,第③行代码是两个矢量的vec2属性相减。

不仅可以使用原型扩展对象函数,还可以扩展对象的属性。 3PiQ8IhtaXy/4dbBRYsMGwel7WRSH3hXR4SREvgkSRcvgRN6EaQlHmKimAktjrIu

点击中间区域
呼出菜单
上一章
目录
下一章
×