前幾天,和朋友聊天,聊到一些js的基礎的時候,有一種‘好像知道,好像又不不知道怎么講的感覺’。。。於是撿起書,自己理一理,歡迎拍磚。
閉包
-
-
如果某個函數被他的父函數之外的一個變量引用,就會形成閉包
-
閉包的作用,就是保存自己私有的變量,通過提供的接口(方法)給外部使用,但外部不能直接訪問該變量。
-
例子(使用閉包):
var test=(function(){ var a=0; return function(){ ++a console.info(a); } })() test();// 1 test();// 2 test();// 3
例子(不使用閉包):
var test=function(){ var a=0; ++a console.info(a); } test();// 1 test();// 1 test();// 1
上面例子形成了閉包,函數第一次執行完后,作用域沒有被回收機制銷毀,所以變量a也被保存下來了,每次調用test,執行后a都會自加1。如果沒有形成閉包,每次調用test,執行后a都會銷毀染后重新創建,執行結果都為1.
作用域
簡單的說,作用域是針對變量的,比如我們創建一個函數a1,函數里面又包了一個子函數a2。此時就存在三個作用域:
全局作用域-a1作用域-a2作用域;即全局作用域包含了a1的作用域,a2的作用域包含了a1的作用域。
當a1在查找變量的時候會先從自身的作用域區查找,找不到再到上一級a2的作用域查找,如果還沒找到就到全局作用域區查找,這樣就形成了一個作用域鏈。
原型
javascript中一切皆對象,每個對象都有一個__proto_ 屬性(由瀏覽器自動創建),該屬性指向它原型。當一個對象在查找一個屬性的時,自身沒有就會根據__proto__ 向它的原型進行查找,如果都沒有,直到查到Object.prototype._proto_為nul,這樣也就形成了原型鏈。
那prototype又是什么?!我們知道可以通過構造函數來創造一個類,prototype的作用就是,讓類的屬性可以被繼承。所以只有構造函數才會有prototype這個屬性。
下面直接用代碼來驗證下:
function Foo(){ this.name='xiaoming' } var foo=new Foo(); foo.age="22" console.info(foo.name)//xiaoming ; foo集成了Foo的name屬性 console.info(foo.__proto__)//object() ; 指向了她的原型Foo.prototype console.info(foo.__proto__ === Foo.prototype)//true console.info(foo.prototype)//undefine ; 只有構造函數才有prototype屬性 console.info(foo.constructor)//function Foo(){……} ; 其實foo並沒有constructor屬性,他只是繼承了原型中的consturctor屬性 console.info(foo.constructor === Foo.prototype.constructor)//true