记录一下 JavaScript 的面向对象和闭包的相关知识
面向对象
计算机原理好像有教……
比喻
手机 这种用来指代一系列物品的总称被称为“类(Class)”,通用特性是可以 打电话 、 发短信 、 上网 。
iPhone、Galaxy 这些物品都属于 手机 这一个 类,虽然具体参数有些差异,但都支持 打电话 、 发短信 、 上网。
使用
通过 构造函数(Construction Function)
构造一个对象,构造的对象将包含共通的属性。
构造函数如:
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
function closure(){
var a = 1000;
function closureReturn(){console.log(a)
}
return closureReturn;
}
接着使用一个变量接收此 function 的返回方法
var closureCall = closure();
closureCall(); // 1000
返回的 1000
即为 closure()
内部的局部变量 a
。
一般来说,当一个 function 执行完毕,内部的所有局部变量便会被销毁,当下次执行时会被重新生成。
但使用闭包,则可以使其持久存在而不随着 function 执行完毕后被销毁。如:
function closure(){
var a = 1000;
function closureReturn(){
a = a + 1;
console.log(a)
}
return closureReturn;
}
接着执行这个返回的 function,可以发现变量 a
仍然可以被访问到。
var closureCall = closure();
closureCall(); // 1001
closureCall(); // 1002
closureCall(); // 1003
注意事项
并不是什么情况下都需要闭包。
闭包使用过多会造成内存占用过大。
this
掌握“我是谁”十分重要。
为何使用
- 使代码清晰明确
- 可以直接操作触发
EventListener
的 DOM 对象。
概括
直接使用:window 对象
例:this
的结果是window
对象。Object 内的 function 调用
例:下列程序中的this
指代object
对象。var object = { a: 1, b: function(){console.log(this.a) // 1 } }
EventListener 的触发调用
例:设有如下 DOM 并且添加了 EventListener,直接调用this
将指代触发的 DOM 元素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
}
```