第十四节 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>
View Code
 1 <!DOCTYPE HTML>
 2 <html>
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>对象组成2</title>
 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>
View Code

第一个面向对象程序:

  为对象添加方法和属性

    this(当前发生事件的对象)详解,事件处理中this的本质

      window:全局方法属于window下的,如下:

<script>
    // function show() {
    //     alert(this);
    // }
    // show();     //返回弹窗“[object Window]”,因为全局方法属于“window”里面的。

    //上述代码相当于
    window.show = function () {
        alert(this);
    };
</script> 

      所以说,this——当前的函数属于谁,this就表示谁

    注意:不能在系统对象(如Date-日期对象、Array-数组对象、RegExp-正则)中随意附加方法、属性,否则会覆盖已有方法、属性,当我们想要创建自己的对象,且不想要系统额外附加的方法、属性等时,我们可以选择object对象,如下:

    object对象:其优点是没有功能,相当于一张白纸,你可以随意写、画,而且还能有效避免与系统属性或方法产出冲突。下面下一个简单的“面向对象程序”如下:

<script>
    var obj = new Object();   //新建对象

    obj.name = 'haha';      //为对象添加属性
    obj.qq = '123456789';

    //为对象添加方法
    obj.showName = function () {
        alert('他的名字叫做:'+this.name);
    };
    obj.showQQ = function () {
        alert('他的QQ号为:'+this.qq);
    };

    obj.showName();     //函数调用
    obj.showQQ();
</script> 

面向对象两种实现方式:

① 工厂方式

  什么是工厂:原料、加工、出厂

  工厂方式:

    用构造函数创建一个类:(构造函数 ,是一种特殊的方法。主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。特别的一个类可以有多个构造函数 ,可根据其参数个数的不同或参数类型的不同来区分它们 即构造函数的重载。   ——百度百科)

    什么是类、对象(实例):模具和零件

  工厂方式的问题:

    没有new

<script>
    function show() {
        alert(this);
    }
    show();     //返回弹窗“[object Window]”,因为全局方法属于“window”里面的。

    new show();     //返回弹窗“[object Object]”,因为函数加了new所以函数中的this就不是指向Window了,而是指向new新创建的对象
    //加了new之后,系统会偷偷为我们做:
    //var this = new Object();  //此时this指向新创建的对象,同时在函数执行结束之后,返回之前做:
    //return this;
</script> 

    函数重复定义:造成资源浪费

  加上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>
View Code

② 原型——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>
View Code
 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>
View Code

总之,在我们编程的时候,基本套路就是“在构造函数里添加属性,另外用原型添加方法”

  原型的小缺陷:

    无法限制覆盖

类和对象对比:

  类:模子——不具备实际功能,用于生产产品

  对象:产品(产品):具备实际功能,就是实际产品

  例如:类Array  Array.push();  //错误语法,因为Array是类,不是对象;

       对象    new arr()  //错误语法,因为系统不存在arr类

所以,其实原型之所以类似于CSS中的类,是因为它的方法是添加到类上的,即直接给一类“对象”添加方法

还有,流行的面向对象编写方式

  用混合方式构造对象

    混合的构造函数/原型方式(Mixed Constructor Function/Prototype Method)    

  原则

    构造函数:加属性

    原型:加方法

  对象命名规范

    类名首字母大写  

原文地址:https://www.cnblogs.com/han-bky/p/10293423.html