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:继承案例
相关文章推荐
- JavaScript(4)__Js基础<字符串>
- JavaScript(3)__Js基础<数组>
- JavaScript(6)__Js基础<对象>
- 从零开始学_JavaScript_系列(15)——js系列<3>(转为字符串,截取字符串)
- JavaScript基础 window.open(url,name)中的name与<a>的target配合使用
- JS---JavaScript面向对象编程<一>:封装
- 从零开始学_JavaScript_系列(16)——js系列<5>(正则表达式)
- js 笔记 第一章在html中使用<javascript>标签 以及 html文档模式
- JavaScript基础学习<二>String类型
- JavaScript入门<1>基础语法
- JavaScript基础学习<四>基本数据和引用类型
- IT前沿技术之node.js篇<一>:Node.js与javascript
- Js_Dom(4)__Dom基础<回流与重绘>
- JavaScript基础-对象<1>
- js 笔记 第一章在html中使用<javascript>标签 以及 html文档模式
- 一个周末掌握IT前沿技术之node.js篇<一>:Node.js与javascript
- js javascript <select>根据value或text设置下拉列表的默认值
- Js_Dom(1)__Dom基础<对象和document>
- JavaScript基础-对象<2>
- 从零开始学_JavaScript_系列(19)——js系列<6>闭包