第十四节 JS面向对象基础
什么是面向对象:在不需要知道它内部结构和原理的情况下,能够有效的使用它,比如,电视、洗衣机等也可以被定义为对象
什么是对象:在Java中对象就是“类的实体化”,在JavaScript中基本相同;对象是一个整体,对外提供一些操作
什么是面向对象:使用对象时,只关注对象提供的功能,不关注其内部细节,比如JQuery
面向对象是一种通用思想,并非只有编程中能用,任何事情都可以用
JS中的面向对象:
面向对象编程(OOP:orient object programming)的特点:
抽象:抓住核心问题,找出自己需要的、跟问题相关的或最主要的属性,把他抽离出来
封装:不考虑内部实现,只考虑功能使用,把自己需要用的功能对象进行封装。
继承:从已有对象中,继承新的对象,即从父类上继承出一些方法、属性,子类,又有一些自己的特性;有多重继承(同时继承两个或多个父级)、多态(不太常用,对于C/C++、Java等强语言比较有用,但是对于JS这种弱语言意义不大)。
对象的组成:
方法——我们之前常叫做函数:过程、动态的
属性——我们之前常叫做变量:状态、静态的
DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>对象组成title>
<script>
//var a = 12; //自定义变量,独立的,不属于任何事物
//alert(a); //返回12
//var arr = [1,2,3,4,5,6];
//arr.a = 12; //自定义属性,私有的,属于某一对象的,即a为属于arr的属性
//alert(arr.a); //返回12
//由上述两段代码可知,变量能做的事情,属性一样能做
/*再入下面两段代码有事一样的功能
function aaa(){ //函数,自由的,跟任何东西没有隶属关系
alert('abc');
}
var arr=[1,2,3,5];
arr.aaa = function(){ //方法,属于一个对象
alert('abc');
};
//函数调用
aaa();
arr.aaa();*/
script>
head>
<body>
body>
html>
1 DOCTYPE HTML> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>对象组成2title> 6 <script> 7 var arr = [1,2,3,4,5,6]; 8 arr.a = 12; //自定义属性,私有的,属于某一对象的,即a为属于arr的属性 9 arr.show = function(){ //方法,属于一个对象 10 alert(this.a); //此时this就是arr本身,相当于 11 alert(arr.a); 12 }; 13 14 //函数调用 15 //arr.show(); 16 script> 17 head> 18 <body> 19 body> 20 html>
第一个面向对象程序:
为对象添加方法和属性
this(当前发生事件的对象)详解,事件处理中this的本质
window:全局方法属于window下的,如下:
所以说,this——当前的函数属于谁,this就表示谁
注意:不能在系统对象(如Date-日期对象、Array-数组对象、RegExp-正则)中随意附加方法、属性,否则会覆盖已有方法、属性,当我们想要创建自己的对象,且不想要系统额外附加的方法、属性等时,我们可以选择object对象,如下:
object对象:其优点是没有功能,相当于一张白纸,你可以随意写、画,而且还能有效避免与系统属性或方法产出冲突。下面下一个简单的“面向对象程序”如下:
面向对象两种实现方式:
① 工厂方式
什么是工厂:原料、加工、出厂
工厂方式:
用构造函数创建一个类:(构造函数 ,是一种特殊的方法。主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。特别的一个类可以有多个构造函数 ,可根据其参数个数的不同或参数类型的不同来区分它们 即构造函数的重载。 ——百度百科)
什么是类、对象(实例):模具和零件
工厂方式的问题:
没有new
函数重复定义:造成资源浪费
加上new
偷偷做了两件事
替你创建了一个空白对象
替你返回了这个对象
new 和 this
1 DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>第一个面向对象程序title> 6 <script> 7 // var obj = new Object(); //新建对象 8 // 9 // obj.name = 'haha'; //为对象添加属性 10 // obj.qq = '123456789'; 11 // 12 // //为对象添加方法 13 // obj.showName = function () { 14 // alert('他的名字叫做:'+this.name); 15 // }; 16 // obj.showQQ = function () { 17 // alert('他的QQ号为:'+this.qq); 18 // }; 19 // 20 // obj.showName(); //函数调用 21 // obj.showQQ(); 22 23 // //由于实际情况中并不会出现只有一个用户的情况,当用户变多时,我们也不能一个一个地创建对象,所以我们把对象可以封装在一个函数内,如下: 24 // function createPerson(name, qq) { //构造函数:因为该函数用于创建一个对象,与其它函数功能不同(但形式几乎没有区别),所以叫构造函数 25 // //构造对象的方式,一般我们把它称作为“工厂方式”的工作流程—— 原料->加工->出厂 26 // //原料 27 // var obj = new Object(); //新建对象 28 // 29 // //加工过程 30 // obj.name = name; //为对象添加属性 31 // obj.qq = qq; 32 // 33 // //为对象添加方法 34 // obj.showName = function () { 35 // alert('他的名字叫做:'+this.name); 36 // }; 37 // obj.showQQ = function () { 38 // alert('他的QQ号为:'+this.qq); 39 // }; 40 // 41 // //出厂 42 // return obj; 43 // } 44 // var obj1 = createPerson('haha', '123456789'); 45 // var obj2 = createPerson('xixi', '987654321'); 46 // 47 // obj1.showName(); 48 // obj1.showQQ(); 49 // 50 // obj2.showName(); 51 // obj2.showQQ(); 52 53 //工厂方式的问题:没有new、函数重复定义,如下: 54 //1.函数重复定义:浪费资源 55 // alert(obj1.showName()==obj2.showName()); //返回False,由此可见虽然两个函数内容相同,但是却不是同一个,因为函数重复定义了。 56 //2.没有new 57 function createPerson(name, qq) { //构造函数:因为该函数用于创建一个对象,与其它函数功能不同(但形式几乎没有区别),所以叫构造函数 58 this.name = name; //为对象添加属性 59 this.qq = qq; 60 61 //为对象添加方法 62 this.showName = function () { 63 alert('他的名字叫做:'+this.name); 64 }; 65 this.showQQ = function () { 66 alert('他的QQ号为:'+this.qq); 67 }; 68 } 69 var obj1 = new createPerson('haha', '123456789'); //此处要加new,否则不能正常执行 70 var obj2 = new createPerson('xixi', '987654321'); 71 72 obj1.showName(); 73 obj1.showQQ(); 74 75 obj2.showName(); 76 obj2.showQQ(); 77 script> 78 head> 79 <body> 80 body> 81 html>
② 原型——prototype
什么是原型
原型是class,修改他可以影响一类元素,即一次给一组元素添加样式,原型就相当于CSS中的class(在JS中叫做“原型”),而与此相对的CSS中的行间样式(在JS中相当于“给对象添加事件”):一次只能给一个元素添加样式
在已有对象中加入自己的属性、方法
原型修改对已有对象的影响
为Array添加sum方法
给对象添加方法,类似于行间样式
给原型添加方法,类似于class
1 DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>原型简介title> 6 <script> 7 var arr1 = new Array(12,55,34,78,676); 8 var arr2 = new Array(12,55,34,78); //在新建一个数组,然后我们想用一个方法,计算出两个数组各个的和,此时我们就用到了“原型” 9 10 // alert(arr1); //输出“12,55,34,78,676” 11 12 Array.prototype.sum = function(){ //类似于“class”, 此处Array为系统“类”,即用原型给系统自带的类添加方法,同样也可以个自定义类添加方法 13 // arr1.sum = function () { //类似于“行间样式” 14 var result = 0; 15 16 for (var i = 0; i < this.length; i++) { 17 result += this[i]; 18 } 19 20 return result; 21 }; 22 23 alert(arr1.sum()); //855 24 alert(arr2.sum()); //179 25 script> 26 head> 27 <body> 28 body> 29 html>
1 DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>原型用到面向对象里title> 6 <script> 7 function createPerson(name, qq) { 8 this.name = name; //为对象添加属性 9 this.qq = qq; 10 11 // //为对象添加方法 12 // this.showName = function () { 13 // alert('他的名字叫做:'+this.name); 14 // }; 15 // this.showQQ = function () { 16 // alert('他的QQ号为:'+this.qq); 17 // }; 18 } 19 createPerson.prototype.showName = function () { //给自定义的类添加方法 20 alert('他的名字叫做:'+this.name); 21 }; 22 createPerson.prototype.showQQ = function () { 23 alert('他的QQ号为:'+this.qq); 24 }; 25 26 var obj1 = new createPerson('haha', '123456789'); //此处要加new,否则不能正常执行 27 var obj2 = new createPerson('xixi', '987654321'); 28 29 // obj1.showName(); 30 // obj1.showQQ(); 31 // 32 // obj2.showName(); 33 // obj2.showQQ(); 34 35 alert(obj1.showName()==obj2.showName()); //此时返回“true”,与工厂方式不同,表示两个方法是同一个方法 36 script> 37 head> 38 <body> 39 body> 40 html>
总之,在我们编程的时候,基本套路就是“在构造函数里添加属性,另外用原型添加方法”
原型的小缺陷:
无法限制覆盖
类和对象对比:
类:模子——不具备实际功能,用于生产产品
对象:产品(产品):具备实际功能,就是实际产品
例如:类Array Array.push(); //错误语法,因为Array是类,不是对象;
对象 new arr() //错误语法,因为系统不存在arr类
所以,其实原型之所以类似于CSS中的类,是因为它的方法是添加到类上的,即直接给一类“对象”添加方法
还有,流行的面向对象编写方式
用混合方式构造对象
混合的构造函数/原型方式(Mixed Constructor Function/Prototype Method)
原则
构造函数:加属性
原型:加方法
对象命名规范
类名首字母大写