JS-函數讀書筆記
1.函數就是對象函數可以存放變量,數組,對象
函數可以當做參數傳遞給其他函數
函數可以返回函數
函數可以擁有方法
2.函數的調用
調用運算符是任何一個產生函數值的表達式之后的一對圓括號。
調用一個函數將暫停當前函數的執行,傳遞控制權和參數給新函數,除了聲明時定義的形參,每個函數接收兩個附加的參數-this和arguments。
this的值取決于調用的模式:
方法調用模式:函數被保存為對象的一個屬性時,稱為方法。方法被調用時,this綁定到該對象。
var obj={
value:0,
increment:function(){
this.value+=1;
}
}
obj.increment();
obj.value;
函數調用模式:當一個函數并非對象的屬性時,它被當作一個函數來調用,this綁定到全局對象(Window),因此不能共享外部函數對對象的訪問權-語言設計的錯誤。當內部函數被調用時,this應該仍綁定到外部函數的this變量。
解決方案:定義一個變量并給它賦值為this
var myObj={
value: 0,
getValue: function(){
return this.value;
}
};
myObj.test=function(){
var that = this
var helper=function(){
that.value+=1;
}();
}
myObj.test();
構造器調用模式:如果一個函數前面帶上new來調用,將會創建一個隱藏連接到該函數的prototype成員的新對象,this將會綁定到新對象上。
var Quo = function(string){
this.status=string;
}
Quo.prototype.get_status=function(){
return this.status;
}
var myQuo=new Quo("confused");
myQuo.get_status();
apply調用模式:apply方法讓我們構建一個參數數組并用其去調用函數。該方法允許我們選擇this的值,apply方法接收兩個參數,第一個就是將被綁定給this的值,如果是null則為Window對象,第二個是參數列表。
var array=[3,4];
var sum=add.apply(null,array);
var Quo = function(string){
this.status=string;
}
Quo.prototype.get_status=function(){
return this.status;
}
var statusObj={
status:"OK"
};
Quo.prototype.get_status.apply(statusObj);
var myObj={
add:function(a,b){
//參數為null或#ff0000,this引用為Window, double函數的alert證明了這一點
alert(this.location.href);
return a+b;
}
}
var array=[3,4];
var sum=myObj.add.apply(null,array);
2.給類型增加方法:待續
3.閉包-能夠讀/寫函數內部的某些變量的子函數,并將這些變量保存在內存中.
討論閉包之前先討論函數作用域
1)函數內的局部變量在函數外部無法訪問。
function f(){
var n=1;
}
alert(n);//error
2)內部函數可以訪問外部函數的局部變量。
function f(){
var n=1;
function inner(){
alert(n);
}
}
因此只要將inner作為返回值,就可以在f外部讀取它的內部變量了。
function f(){
var n=1;
function inner(){
alert(n);
}
return inner;
}
f()();
閉包就是將函數內部和函數外部連接起來的一座橋梁。如果把父函數當作對象使用,把閉包當作它的公共函數,把內部變量當作它的私有屬性。
理解內部函數能訪問外部函數的實際變量而無須復制:
var add_handles=function(nodes){
for(var i=0;i<nodes.length;i++){
nodes[i].onclick=function(e){
alert(i);
}
}
}
var add_handles=function(nodes){
for(var i=0;i<nodes.length;i++){
nodes[i].onclick=function(i){
return function(e){
alert(e);
}
}(i);
}
}
閉包用途:
1)讀取函數內部的局部變量
2)將變量的值始終保存在內存中,因為f是inner的父函數,而inner被賦給了一個全局變量,導致inner始終在內存中,而inner的存在依賴于f,因此f也始終在內存中,不會在調用結束后被垃圾回收機制回收。
3)通過保護變量的安全實現JS私有屬性和私有方法(不能被外部訪問)
缺點:閉包使得函數中的變量都被保存在內存中,內存消耗很大,不能濫用閉包。
4.模塊
一個定義了私有變量和函數的函數,利用閉包創建可以訪問私有變量和函數的特權函數,然后返回這個特權函數。
提供接口卻隱藏狀態與實現的函數或對象。摒棄了全局變量。