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

JavaScript(7)__Js基础<构造>

2017-08-07 22:15 253 查看

1:对象的概念

“面向对象编程”(Object OrientedProgramming,缩写为OOP)是目前主流的编程范式。它的核心思想是将真实世界中各种复杂的关系,抽象为一个个对象,然后由对象之间的分工与合作,完成对真实世界的模拟。

传统的过程式编程(proceduralprogramming)由一系列函数或一系列指令组成,而面向对象编程的程序由一系列对象组成。每一个对象都是功能中心,具有明确分工,可以完成接受信息、处理数据、发出信息等任务。因此,面向对象编程具有灵活性、代码的可重用性、模块性等特点,容易维护和开发,非常适合多人合作的大型软件项目。

 

2:对象的实质

(1)“对象”是单个实物的抽象。

     一本书、一辆汽车、一个人都可以是“对象”,一个数据库、一张网页、一个与远程服务器的连接也可以是“对象”。当实物被抽象成“对象”,实物之间的关系就变成了“对象”之间的关系,从而就可以模拟现实情况,针对“对象”进行编程。

(2)“对象”是一个容器,封装了“属性”(property)和“方法”(method)。

所谓“属性”,就是对象的状态;所谓“方法”,就是对象的行为(完成某种任务)。比如,我们可以把动物抽象为animal对象,“属性”记录具体是那一种动物,“方法”表示动物的某种行为(奔跑、捕猎、休息等等)。

 

 

3:构造函数

“面向对象编程”的第一步,就是要生成“对象”。

前面说过,“对象”是单个实物的抽象。通常需要一个模板,表示某一类实物的共同特征,然后“对象”根据这个模板生成。   

典型的面向对象编程语言(比如 C++ 和 Java),存在“类”(class)这个概念。所谓“类”就是对象的模板,对象就是“类”的实例。但是,JavaScript语言的对象体系,不是基于“类”的,而是基于构造函数(constructor)和原型链(prototype)。

JavaScript语言使用构造函数(constructor)作为对象的模板。所谓“构造函数”,就是专门用来生成“对象”的函数。它提供模板,描述对象的基本结构。一个构造函数,可以生成多个对象,这些对象都有相同的结构。

构造函数的写法就是一个普通的函数,但是有自己的特征和用法。

 4:构造函数的特点



上面代码中,Vehicle就是构造函数,它提供模板,用来生成对象实例。为了与普通函数区别,构造函数名字的第一个字母通常大写。

构造函数的特点有两个。

    函数体内部使用了this关键字,代表了所要生成的对象实例。

生成对象的时候,必需用new命令,调用Vehicle函数。

 

5:new 命令

new命令的作用,就是执行构造函数,返回一个实例对象。



上面代码通过new命令,让构造函数Vehicle生成一个实例对象,保存在变量v中。这个新生成的实例对象,从构造函数Vehicle继承了price属性。在new命令执行时,构造函数内部的this,就代表了新生成的实例对象,this.price表示实例对象有一个price属性,它的值是1000。

使用new命令时,根据需要,构造函数也可以接受参数。

6:构造函数的缺点

JavaScript通过构造函数生成新对象,因此构造函数可以视为对象的模板。实例对象的属性和方法,可以定义在构造函数内部。



上面代码的Cat函数是一个构造函数,函数内部定义了name属性和color属性,所有实例对象都会生成这两个属性。但是,这样做是对系统资源的浪费,因为同一个构造函数的对象实例之间,无法共享属性。



cat1和cat2是同一个构造函数的实例。但是,它们的meow方法是不一样的,就是说每新建一个实例,就会新建一个meow方法。这既没有必要,又浪费系统资源,因为所有meow方法都是同样的行为,完全应该共享。

7:原型

JavaScript的每个对象都继承另一个对象,后者称为“原型”(prototype)对象。只有null除外,它没有自己的原型对象。原型对象上的所有属性和方法,都能被派生对象共享。这就是JavaScript继承机制的基本设计。

通过构造函数生成实例对象时,会自动为实例对象分配原型对象。每一个构造函数都有一个prototype属性,这个属性就是实例对象的原型对象。



原型对象的属性不是实例对象自身的属性。只要修改原型对象,变动就立刻会体现在所有实例对象上。



如果实例对象自身就有某个属性或方法,它就不会再去原型对象寻找这个属性或方法。

总结一下,原型对象的作用,就是定义所有实例对象共享的属性和方法。这也是它被称为原型对象的含义,而实例对象可以视作从原型对象衍生出来的子对象。



Animal.prototype对象上面定义了一个walk方法,这个方法将可以在所有Animal实例对象上面调用。

由于JavaScript的所有对象都有构造函数,而所有构造函数都有prototype属性(其实是所有函数都有prototype属性),所以所有对象都有自己的原型对象。

8:原型链

对象的属性和方法,有可能是定义在自身,也有可能是定义在它的原型对象。由于原型本身也是对象,又有自己的原型,所以形成了一条原型链(prototype chain)。比如,a对象是b对象的原型,b对象是c对象的原型,以此类推。

如果一层层地上溯,所有对象的原型最终都可以上溯到Object.prototype,即Object构造函数的prototype属性指向的那个对象。那么,Object.prototype对象有没有它的原型呢?回答可以是有的,就是没有任何属性和方法的null对象,而null对象没有自己的原型。

如果对象自身和它的原型,都定义了一个同名属性,那么优先读取对象自身的属性,这叫做“覆盖”(overiding)。

9:Constructor属性

prototype对象有一个constructor属性,默认指向prototype对象所在的构造函数。

10:instanceof

instanceof运算符返回一个布尔值,表示指定对象是否为某个构造函数的实例。



instanceof运算符的左边是实例对象,右边是构造函数。

 

注意,instanceof运算符只能用于对象,不适用原始类型的值。



11:继承

让一个构造函数继承另一个构造函数,是非常常见的需求。

这可以分成两步实现。第一步是在子类的构造函数中,调用父类的构造函数。



上面代码中,Sub是子类的构造函数,this是子类的实例。在实例上调用父类的构造函数Super,就会让子类实例具有父类实例的属性。

第二步,是让子类的原型指向父类的原型,这样子类就可以继承父类原型。



上面代码中,Sub.prototype是子类的原型,要将它赋值为Object.create(Super.prototype),而不是直接等于Super.prototype。否则后面两行对Sub.prototype的操作,会连父类的原型Super.prototype一起修改掉。



另外一种写法是Sub.prototype等于一个父类实例。(不推荐使用)



12:继承案例

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