记录一下JavaScript的面向对象和闭包的相关知识

面向对象

计算机原理好像有教……

比喻

手机 这种用来指代一系列物品的总称被称为“类(Class)”,通用特性是可以打电话发短信上网
iPhoneGalaxy 这些物品都属于手机这一个,虽然具体参数有些差异,但都支持打电话发短信上网

使用

通过 构造函数(Construction Function) 构造一个对象,构造的对象将包含共通的属性。
构造函数如:

1
2
3
4
5
function MobilePhone(){
this.makeCall = console.log("Make Call!");
this.sendSMS = console.log("Send SMS!");
this.browsing = console.log("Internet Browsing!");
}

如此,使用var iPhone = new MobilePhone()创建一个新的 iPhone 对象后,则它就可以“打电话” (iPhone.makeCall())了。

为何使用

  • 封装(不用过多操心对象本身的事情)
  • 代码重用(省得给每个 Object 都去定义属性)
    etc…

深入

使用 原型 (prototype)。原型类似于对象属性的默认值。在没有覆盖属性的时候,调用属性将会返回原型的值(若已定义)。
优点: 原型值不可见(等同封装)
用法:Object.prototype 进行操作对象的原型值。

闭包

很强大,但不是什么地方都要用到

概括

用来操作 function 内部的变量,并使其持久地存在。

为何使用

  • 私有化(避免外部直接操作内部数据)
  • 灵活(延伸 function 的作用链,通过返回的 function 直接控制内部变量而无须直接操作变量值)
  • 避免全局变量污染

使用

首先定义 function

1
2
3
4
5
6
7
8
9
function closure(){
var a = 1000;

function closureReturn(){
console.log(a)
}

return closureReturn;
}

接着使用一个变量接收此 function 的返回方法

1
2
3
var closureCall = closure();

closureCall(); // 1000

返回的 1000 即为 closure() 内部的局部变量 a


一般来说,当一个 function 执行完毕,内部的所有局部变量便会被销毁,当下次执行时会被重新生成。
但使用闭包,则可以使其持久存在而不随着 function 执行完毕后被销毁。如:

1
2
3
4
5
6
7
8
9
10
function closure(){
var a = 1000;

function closureReturn(){
a = a + 1;
console.log(a)
}

return closureReturn;
}

接着执行这个返回的 function,可以发现变量 a 仍然可以被访问到。

1
2
3
4
5
var closureCall = closure();

closureCall(); // 1001
closureCall(); // 1002
closureCall(); // 1003

注意事项

并不是什么情况下都需要闭包。
闭包使用过多会造成内存占用过大。

this

掌握“我是谁”十分重要。

为何使用

  • 使代码清晰明确
  • 可以直接操作触发EventListener的 DOM 对象。

概括

  • 直接使用:window 对象
    例:this 的结果是 window 对象。

  • Object 内的 function 调用
    例:下列程序中的 this 指代 object 对象。

    1
    2
    3
    4
    5
    6
    var object = {
    a: 1,
    b: function(){
    console.log(this.a) // 1
    }
    }
  • EventListener 的触发调用
    例:设有如下 DOM 并且添加了 EventListener,直接调用 this 将指代触发的 DOM 元素

    1
    2
    3
    4
    5
    6
    7
    8
    9
    HTML:
    <span id="dom" class="dom-class" data-id="1"></span>

    JavaScript:
    document.getElementByID("dom").addEventListener('click', callFunc, false)
    function callFunc(){
    console.log(this) // ID 为 dom 的元素
    console.log(this.getAttribute("data-id")) // 1
    }