zoukankan      html  css  js  c++  java
  • JavaScript 面向对象(一) —— 基础篇

    学好JS的面向对象,能很大程度上提高代码的重用率,像jQuery,easyui等,这篇博客主要从细节上一步步讲JS中如何有效地创建对象,也可以看到常见的创建对象的方式,最后也会附上一些JS面向对象的案例。

    一、面向对象(Java面向对象亦是如此)

    1.对象:对象是一个整体,对外提供一些操作。

    2.面向对象:使用对象时,只关注对象提供的功能,不关注其内部细节。比如电脑——有鼠标、键盘,我们只需要知道怎么使用鼠标,敲打键盘即可,不必知道为何点击鼠标可以选中、敲打键盘是如何输入文字以及屏幕是如何显示文字的。总之我们没必要知道其具体工作细节,只需知道如何使用其提供的功能即可,这就是面向对象。

    3.JS的对象组成:方法 和 属性

    在JS中,有函数、方法、事件处理函数、构造函数,其实这四个都是函数,只是作用不同。函数是独立的存在,方法属于一个对象,事件处理函数用来处理一个事件,构造函数用来构造对象。

    首先通过常用的数组来认识下JS的对象:

     1 <!DOCTYPE html>
     2 <html>
     3     <head>
     4         <meta charset="UTF-8">
     5         <title></title>
     6         <script>
     7             
     8             /**
     9              * 定义一个数组
    10              */
    11             var arr = [1, 2, 3, 4, 5];
    12             
    13             /**
    14              * 弹出 object
    15              * 说明数组就是个对象
    16              */
    17             alert(typeof arr); 
    18             
    19             /**
    20              * 弹出5
    21              * 对象的属性 length
    22              */
    23             alert(arr.length); 
    24             
    25             /**
    26              * 对象的方法 push
    27              * 弹出 1,2,3,4,5,6
    28              */
    29             arr.push(6); 
    30             alert(arr); 
    31         </script>
    32     </head>
    33     <body>
    34     </body>
    35 </html>

    4.认识下JS中的this以及全局对象window

     1 <!DOCTYPE html>
     2 <html>
     3     <head>
     4         <meta charset="UTF-8">
     5         <title></title>
     6         <script>
     7             /**
     8              * 定义一个全局函数
     9              */
    10             function show(){
    11                 alert(this);
    12             }
    13             //调用show()
    14             show();
    15             
    16         </script>
    17     </head>
    18     <body>
    19     </body>
    20 </html>

     此处的show()函数为一个全局函数,调用show(),alert(this)弹出来的是window对象,说明全局函数属于window。上面定义的show()等于为window添加一个方法,全局的函数和变量都是属于window的,上面的定义等价于下面。

     1 <!DOCTYPE html>
     2 <html>
     3     <head>
     4         <script>
     5             /**
     6              * 为window定义一个show方法
     7              */
     8             window.show = function(){
     9                 alert(this);
    10             }
    11             //调用show()
    12             window.show();
    13             
    14         </script>
    15     </head>
    16 </html>

    同样的我们也可以根据自己的需求为其它的对象添加方法,比如显示数组:

    但是我们不能在系统对象中随意附加方法和属性,否则可能会覆盖已有方法、属性。

     1 <!DOCTYPE html>
     2 <html>
     3     <head>
     4         <script>
     5             var arr = [1,2,3,4,5];
     6             arr.show = function(){
     7                 alert(this);
     8             }
     9             arr.show(); //弹出 1,2,3,4,5
    10         </script>
    11     </head>
    12 </html>

    从上面的例子也可以看出来,this即表示当前函数的调用者是谁,但是在一种情况下不是的,就是使用new 来创建对象时,this并不是指向调用者的,在后面会有说明。

    window是全局对象,可以看下属于window的全局属性和全局方法:

     

    二、JS中自定义对象,逐步分析JS中的创建对象

    1.通过Object创建简单对象:

    这种方式有一个非常大的弊端,就是如果我有多个人怎么办,每次都要新建一个对象,然后添加属性、方法,这种方式是一次性的,会产生大量重复代码,这是不可取的。

     1 <!DOCTYPE html>
     2 <html>
     3     <meta charset="UTF-8" />
     4     <head>
     5         <script>
     6             /**
     7              * 创建一个新对象
     8              * new Object()创建出来的对象几乎是空白的,需要自己添加属性,方法
     9              */
    10             var person = new Object();
    11             //为person对象添加属性
    12             person.name = "jiangzhou";
    13             person.age = 22;
    14             //为person对象添加方法
    15             person.showName = function(){
    16                 alert("姓名:"+this.name);
    17             }
    18             person.showAge = function(){
    19                 alert("年龄:"+this.age);
    20             }
    21             //调用对象的方法
    22             person.showName();
    23             person.showAge();
    24             
    25         </script>
    26     </head>
    27 </html>

    2.用工厂方式来构造对象:工厂,简单来说就是投入原料、加工、出厂。

    通过构造函数来生成对象,将重复的代码提取到一个函数里面,避免像第一种方式写大量重复的代码。这样我们在需要这个对象的时候,就可以简单地创建出来了。

     1 <!DOCTYPE html>
     2 <html>
     3     <meta charset="UTF-8" />
     4     <head>
     5         <script>
     6             //构造函数:工厂
     7             function createPerson(name, age){
     8                 var person = new Object();
     9                 
    10                 //原料
    11                 person.name = name;
    12                 person.age = age;
    13                 
    14                 //加工
    15                 person.showName = function(){
    16                     alert("姓名:"+this.name);
    17                 }
    18                 person.showAge = function(){
    19                     alert("年龄:"+this.age);
    20                 }
    21                 //出厂
    22                 return person;
    23             }
    24             //创建两个对象
    25             var p1 = createPerson("jiangzhou", 22);
    26             var p2 = createPerson("tom", 20);
    27             
    28             //调用对象方法
    29             p1.showName();
    30             p1.showAge();
    31             
    32             p2.showName();
    33             p2.showAge();
    34             
    35         </script>
    36     </head>
    37 </html>

    但是,这种方式有两个缺点:

    ①一般我们创建对象是通过new来创建,比如new Date(),这里使用的是方法创建。使用new来创建可以简化一些代码,也带来一些新的特性。

    ②每个对象都有一套自己的方法,浪费资源(虽然对于现在的计算机来说不算什么,但我们尽量将设计做到最好就行了)。

    这里为什么说每个对象都有自己的一套方法呢,是因为创建function()的时候其本质是通过new Function()来创建的,会诞生一个新的函数对象,所以每个对象的方法是不一样的,这样就存在资源浪费的问题了。看第25行代码。

     1 <!DOCTYPE html>
     2 <html>
     3     <meta charset="UTF-8" />
     4     <head>
     5         <script>
     6             
     7             function createPerson(name, age, sex){
     8                 var person = new Object();
     9                 
    10                 person.name = name;
    11                 person.age = age;
    12                 person.sex = sex;
    13                 
    14                 person.showName = function(){
    15                     alert("姓名:"+this.name);
    16                 }
    17                 person.showAge = function(){
    18                     alert("年龄:"+this.age);
    19                 }
    20                 
    21                 /**
    22                  *  person.showSex = function(){} 等价于 person.showSex = new Function('');
    23                  *  也就是说我们在创建这个函数的时候就是新建了一个对象。
    24                  */
    25                 person.showSex = new Function('alert("性别:"+this.sex)');
    26                 
    27                 return person;
    28             }
    29             
    30             //创建两个对象
    31             var p1 = createPerson("jiangzhou", 22, "");
    32             var p2 = createPerson("Lyli", 20, "");
    33             
    34             alert(p1.showName == p2.showName); //false
    35             
    36         </script>
    37     </head>
    38 </html>

    3.使用new 来创建JS对象

     1 <!DOCTYPE html>
     2 <html>
     3     <meta charset="UTF-8" />
     4     <head>
     5         <script>
     6             
     7             function Person(name, age){
     8                 /**
     9                  * 可以假想成系统会创建一个对象
    10                  * var this = new Object();
    11                  */
    12                 
    13                 alert(this); //弹出Object
    14                 
    15                 this.name = name;
    16                 this.age = age;
    17                 
    18                 this.showName = function(){
    19                     alert("姓名:"+this.name);
    20                 }
    21                 this.showAge = function(){
    22                     alert("年龄:"+this.age);
    23                 }
    24                 
    25                 /**
    26                  * 假想返回了对象
    27                  * return this;
    28                  */
    29             }
    30             
    31             //创建两个对象
    32             var p1 = new Person("jiangzhou", 22);//可以看到在外面new了在function里面就不用new了;在function里面new了,在外面就不用new了;O(∩_∩)O~
    33             var p2 = new Person("Lyli", 20);
    34             
    35             alert(p1.showName == p2.showName); //false
    36             
    37         </script>
    38     </head>
    39 </html>

    弹出信息显示this即是一个Object(第13行代码)。在方法调用前使用new来创建,function内的this会指向一个新创建的空白对象,而不是指向方法调用者,而且会自动返回该对象。

    但是这种方式只解决了第一个问题,每个对象还是有自己的一套方法(第35行代码)。

     4.在function原型(prototype)上进行扩展 —— 最终版

    原型添加的方法不会有多个副本,不会浪费资源,所有的对象只有一套方法(看第29行代码)。 至于为什么是用的一套方法呢,看第31行代码:因为所有的方法都等于原型上的方法。

     1 <!DOCTYPE html>
     2 <html>
     3     <meta charset="UTF-8" />
     4     <head>
     5         <script>
     6             
     7             /**
     8              * Person构造函数:在JS中,构造函数其实就可以看成类,对某个对象的抽象定义。
     9              * @param {Object} name
    10              * @param {Object} age
    11              */
    12             function Person(name, age){
    13                 //属性:每个对象的属性各不相同
    14                 this.name = name;
    15                 this.age = age;
    16             }
    17             //在原型上添加方法,这样创建的所有对象都是用的同一套方法
    18             Person.prototype.showName = function(){
    19                 alert("姓名:"+this.name);
    20             }
    21             Person.prototype.showAge = function(){
    22                 alert("年龄:"+this.age);
    23             }
    24             
    25             //创建两个对象
    26             var p1 = new Person("jiangzhou", 22);
    27             var p2 = new Person("Lyli", 20);
    28             
    29             alert(p1.showName == p2.showName); //true
    30             //这里为什么两个对象的方法是相等的呢,可以看成如下
    31             alert(p1.showName == Person.prototype.showName); //true
    32             
    33         </script>
    34     </head>
    35 </html>

    通过prototype我们还可以很方便的扩展系统对象,按照自己的需求来扩展,而且又能适用于所有地方,又不会浪费资源。如下面对Array进行扩展,求数组和的方法。

     1 <!DOCTYPE html>
     2 <html>
     3     <head>
     4         <meta charset="UTF-8">
     5     </head>
     6     <script>
     7         /**
     8          * 对数组原型扩展一个求和的方法;
     9          * 注意不能只加在某个数组对象上,那样的话只能在那个对象上适用。
    10          */
    11         Array.prototype.sum = function(){
    12             var sum = 0;
    13             for(var i=0;i<this.length;i++){
    14                 sum += this[i];
    15             }
    16             return sum;
    17         }
    18         //通过new Array() 和 [] 创建数组完全是一样的效果。
    19         var arr1 = new Array(1,2,3,4,5,6);
    20         var arr2 = [11,22,33,44,55];
    21         
    22         alert(arr1.sum());
    23         alert(arr2.sum());
    24         
    25         alert(arr1.sum == arr2.sum); //true
    26         alert(arr2.sum == Array.prototype.sum); //true
    27     </script>
    28 </html>

     

     三、案例:JavaScript 面向对象(二) —— 案例篇

  • 相关阅读:
    201671010105 201620172《Java程序设计》第四章学习心得
    201671010105 201620172《Java程序设计》第一、第二章学习心得
    201671010105 201620172《Java程序设计》第三章学习心得
    201671010105 201620172《Java程序设计》第四周学习心得
    计算三个数字的大小,按从小到大顺序输出。
    js实现网页的两个input标签内的数值加减
    传入一个4位数的整数,进行简单的加密,并1和4,2和3交换输出
    一些简单的循环案例
    计算任意两个个位整数之间所能组成的奇数个数
    js判断输入的年份是否为闰年
  • 原文地址:https://www.cnblogs.com/chiangchou/p/js-oop1.html
Copyright © 2011-2022 走看看