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></ 6         script 7             
 8             /**
 9              * 定义一个数组
10              */
11             var arr = [1,2345];
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         </32     33     body34     35 >

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

 7              8              * 定义一个全局函数
 9              10             function show(){
11                 alert(this);
12             }
//调用show()
            show();
15             
16         17     18     19     20 >

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

 5              6              * 为window定义一个show方法
 7                          window.show = (){
10             window.show();
13             
14         15     16 >

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

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

            arr.show  7             arr.show(); 弹出 1,5
10         11     12 >

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

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

 

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

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

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

="UTF-8" />
 4      6                          * 创建一个新对象
             * new Object()创建出来的对象几乎是空白的,需要自己添加属性,方法
 person new Object();
为person对象添加属性
            person.name "jiangzhou;
13             person.age 2214             为person对象添加方法
            person.showName 16 姓名:+.name);
18             person.showAge 19 年龄:.age);
21             调用对象的方法
22             person.showName();
            person.showAge();
25         26     27 >

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

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

构造函数:工厂
 createPerson(name,age){
 8                  9                 
10                 原料
                person.name  name;
                person.age  age;
13                 
14                 加工
                person.showName                     alert(                }
                person.showAge 21                 出厂
22                 return person;
24             创建两个对象
 p1  createPerson(26              p2 tom2027             
28             调用对象方法
            p1.showName();
            p1.showAge();
31             
32             p2.showName();
33             p2.showAge();
34             
35         36     37 >

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

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

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

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

 6             
                person.sex  sex;
20                 
                 *  person.showSex = function(){} 等价于 person.showSex = new Function('');
                 *  也就是说我们在创建这个函数的时候就是新建了一个对象。
24                  25                 person.showSex  Function('alert("性别:"+this.sex));
26                 
27                 28 29             
30             31             32             Lyli33             
34             alert(p1.showName == p2.showName); false
35             
36         37     38 >

3.使用new 来创建JS对象

 Person(name,1)">                 * 可以假想成系统会创建一个对象
                 * var this = new Object();
11                  12                 
13 ); 弹出Object
14                 
15                 .name 16                 .age 17                 
18                 .showName .showAge 24                 
25                                  * 假想返回了对象
                 * return this;
28                  30             
 Person();可以看到在外面new了在function里面就不用new了;在function里面new了,在外面就不用new了;O(∩_∩)O~
33             35 36             
37         38     39 >

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

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

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

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

             * Person构造函数:在JS中,构造函数其实就可以看成类,对某个对象的抽象定义。
             * @param {Object} name
             * @param {Object} age
11              12             13                 属性:每个对象的属性各不相同
17             在原型上添加方法,这样创建的所有对象都是用的同一套方法
            Person.prototype.showName             Person.prototype.showAge 27             28             
29 true
这里为什么两个对象的方法是相等的呢,可以看成如下
31  Person.prototype.showName); 32             
33         >

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

 5      6      7                  * 对数组原型扩展一个求和的方法;
         * 注意不能只加在某个数组对象上,那样的话只能在那个对象上适用。
10                  Array.prototype.sum  sum 0for( i;i<.length;i++){
                sum += [i];
16              sum;
        }
18         通过new Array() 和 [] 创建数组完全是一样的效果。
19          arr1  Array(20          arr2 1133445521         
        alert(arr1.sum());
        alert(arr2.sum());
24         
        alert(arr1.sum  arr2.sum); 26         alert(arr2.sum  Array.prototype.sum); 27     28 >

 

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

 

相关文章

kindeditor4.x代码高亮功能默认使用的是prettify插件,prett...
这一篇我将介绍如何让kindeditor4.x整合SyntaxHighlighter代...
js如何实现弹出form提交表单?(图文+视频)
js怎么获取复选框选中的值
js如何实现倒计时跳转页面
如何用js控制图片放大缩小