下面屬於javascript內部物件的有_JavaScript基礎內容中閉包以及常用函式
技術標籤:下面屬於javascript內部物件的有
接上文,JavaScript基礎內容中的函式。
我們這次把函式剩下的全部分享完。各位可要用心看嘍。
11、bind
bind 是建立了一個新函式而不是修改一個函式。新函式的行為和原來函式的行為一樣,但他的接收者是我們給定的物件,而原有函式的接收者保持不變。
functionf(){
returnthis.a;
}
varg=f.bind({a:"azerty"});
console.log(g());//azerty
varo={a:37,f:f,g:g};
console.log(o.f(),o.g());//37,azerty
12、 匿名函式立即呼叫
(function(a,b){
alert(a+b);
})(1,2);
13、 函式的閉包
目前先了解,後期見多了,就知道作用了函式的內部,還可以定義另一個函式,這就是閉包(closure),即定義在函式體內部的函式。閉包只在宣告它的函式內部有效。
functionf(){
varc=function(){};
}
上面的程式碼中,c 是定義在函式 f 內部的函式,因此 c 就是 f 的閉包。
一旦外層函式返回閉包,我們就可以通過閉包,從外部讀取函式的內部變數
functionf(){
varv=1;
varc=function(){
returnv;
};
returnc;
}
varo=f();
o()//1
閉包不僅可以讀取函式內部變數,還可以使得內部變數記住上一次呼叫時的運算結果。
functioncreateIncrementor(start){
returnfunction(){
returnstart++;
};
}
varinc=createIncrementor(5);
inc()//5
inc()//6
inc()//7
14、 常用函式
a)、字串
◦ charAt(idx):返回指定位置處的字元
◦ indexOf(Chr):返回指定子字串的位置,從左到右。找不到返回-1
◦ substr(m,n):返回給定字串中從 m 位置開始,取 n 個字元,如果引數 n 省略,則意味著取到字串末尾。
◦ substring(m,n):返回給定字串中從 m 位置開始,到 n 位置結束,如果引數 n省略,則意味著取到字串末尾。
◦ toLowerCase():將字串中的字元全部轉化成小寫。
◦ toUpperCase():將字串中的字元全部轉化成大寫。
◦ length: 屬性,不是方法,返回字串的長度。
b)、數學
◦ Math.random()
◦ Math.ceil() :天花板 大於最大整數
◦ Math.floor() :地板 小於最小整數
c)、日期
◦ getyear, getmonth, …
◦ setyear, setmonth, …
◦ toLoacaleString()
<divid="dv001"onclick="Clock(this);">clickdiv>
/*
-paramclockDiv
-傳入的div物件
*/
functionClock(clockDiv){
this.clockDiv=clockDiv;
this.getCurrentDate=function(){
//獲取當前日期
varcurrDate=newDate();
//分別獲取年、月、日、時、分、秒
varcurrDateTime=currDate.getYear();
currDateTime+="-";
currDateTime+=(currDate.getMonth()+1);
currDateTime+="-";
currDateTime+=currDate.getDate();
currDateTime+="";
currDateTime+=currDate.getHours();
currDateTime+=":";
currDateTime+=currDate.getMinutes();
currDateTime+=":";
currDateTime+=currDate.getSeconds();
returncurrDateTime;
}();
//將當前時間賦值到div物件中
this.clockDiv.innerHTML=this.getCurrentDate;
}
e)、編碼與解碼 :
中文在計算機世界裡面不佔優勢,外國人發明的,再說中文文字也太多:
編碼:encodeURI() -->編碼引數【key=value】、 encodeURIComponent()-->編碼所有 【整個uri地址編碼】
解碼:decodeURI() 、decodeURIComponent()
alert(encodeURI("http://www.baidu.com/index.jsp?姓名=王大錘"));
alert(encodeURIComponent("http://www.baidu.com/index.jsp?uname=王大錘"));
alert(decodeURI("http://www.baidu.com/index.jsp?uname=%E7%8E%8B%E5%A4%A7%E9%94%A4"));
alert(decodeURIComponent("http://www.baidu.com/index.jsp?uname=王大錘"));
15、 this
函式的難點之: this:
this 指定了上下文物件,當然如果沒有指定就會指定到全域性變數,window ;JavaScript 是一種指令碼語言,支援函數語言程式設計、閉包、基於原型的繼承等高階功能。JavaScript 一開始看起來感覺會很容易入門,但是隨著使用的深入,你會發現 JavaScript其實很難掌握,有些基本概念讓人匪夷所思。其中 JavaScript 中的 this 關鍵字,就是一個比較容易混亂的概念,在不同的場景下,this 會化身不同的物件。有一種觀點認為,只有正確掌握了JavaScript 中的 this 關鍵字,才算是邁入了 JavaScript 這門語言的門檻。在主流的面向物件的語言中(例如 Java,C#等),this 含義是明確且具體的,即指向當前物件。一般在編譯期繫結。而 JavaScript 中 this 在執行期進行繫結的,這是JavaScript 中 this 關鍵字具備多重含義的本質原因。JavaScript 由於其在執行期進行繫結的特性,JavaScript 中的 this 可以是全域性物件、當前物件或者任意物件,這完全取決於函式的呼叫方式。JavaScript 中函式的呼叫有以下幾種方式:作為物件方法呼叫,作為函式呼叫,作為建構函式呼叫,和使用 apply 或 call呼叫。常言道,字不如表,表不如圖。為了讓人更好的理解 JavaScript this 到底指向什麼?下面用一張圖(JavaScript this 決策樹)來進行解釋:
varpoint={
x:0,
y:0,
moveTo:function(x,y){
this.x=this.x+x;
this.y=this.y+y;
}
};
point.moveTo(1,1);//this繫結到當前物件,即point物件
point.moveTo()函式在 "JavaScript this 決策樹"中進行判定的過程是這樣的:
1)point.moveTo 函式呼叫是用 new 進行呼叫的麼?這個明顯不是,進入“否”分支,即函式是否用 dot(.)進行呼叫?;
2)point.moveTo 函式是用 dot(.)進行呼叫的,即進入“是”分支,即這裡的 this指向 point.moveTo 中.之前的物件 point;
圖解 point.moveTo 函式的 this 指向什麼的解析圖如下圖所示:
再舉例,看下面的程式碼:
functionfunc(x){
this.x=x;
}
func(5);//this是全域性物件window,x為全域性變數
x;//x=>5
func()函式在 "JavaScript this 決策樹(非嚴格模式)"中進行判定的過程是這樣的:
嚴格模式是一種將更好的錯誤檢查引入程式碼中的方法。在使用嚴格模式時,無法使用隱式宣告的變數、將值賦給只讀屬性或將屬性新增到不可擴充套件的物件等
1、 嚴格模式的目的
1) 消除 Javascript 語法的一些不合理、不嚴謹之處,減少一些怪異行為
2)消除程式碼執行的一些不安全之處,保證程式碼執行的安全
3) 提高編譯器效率,增加執行速度
4) 為未來新版本的 Javascript 做好鋪墊
2、宣告嚴格模式
可以通過在檔案、程式或函式的開頭新增 "use strict"; 來宣告嚴格模式。此類宣告稱作“指令序言”。嚴格模式宣告的範圍取決於其上下文。如果在全域性上下文(函式的範圍之外)中宣告嚴格模式,則程式中的所有程式碼都處於嚴格模式。如果在函式中宣告嚴格模式,則函式中的所有程式碼都處於嚴格模式。
"usestrict";//seestrictmode
functiontestFunction(){
vartestvar=4;
returntestvar;
}
//Thiscausesasyntaxerror.
testvar=5;
functionf1(){
returnthis;
}
console.log(f1()===window);//globalobjectfalse
functionf2(){
"usestrict";//seestrictmode
returnthis;
}
console.log(f2()===undefined);//true
針對作為函式直接呼叫的方式,下面看一個複雜的例子:
varpoint={
x:0,
y:0,
moveTo:function(x,y){
//內部函式
varmoveX=function(x){
this.x=x;//this 指向什麼?window
};
//內部函式
varmoveY=function(y){
this.y=y;//this 指向什麼?window
};
moveX(x);
moveY(y);
}
};
point.moveTo(1,1);
point.x;//=>0
point.y;//=>0
x;//=>1
y;//=>1
point.moveTo(1,1)函式實際內部呼叫的是 moveX()和 moveY()函式, moveX()函式內部的 this 在"JavaScript this 決策樹"中進行判定的過程是這樣的:
1)moveX(1)函式呼叫是用 new 進行呼叫的麼?這個明顯不是,進入“否”分支,即函式是否用 dot(.)進行呼叫?;
2)moveX(1)函式不是用 dot(.)進行呼叫的,即進入“否”分支,即這裡的 this 指向全域性變數 window,那麼 this.x 實際上就是 window.x;
下面看一下作為建構函式呼叫的例子:
functionPoint(x,y){
this.x=x;//this?
this.y=y;//this?
}
varnp=newPoint(1,1);
np.x;//1
varp=Point(2,2);//沒有return就是undefined
p.x;//error,p是一個空物件undefined
window.x;//2
Point(1,1)函式在 var np=new Point(1,1)中的 this 在 "JavaScript this 決策樹"中進行判定的過程是這樣的:
1)var np=new Point(1,1)呼叫是用 new 進行呼叫的麼?這個明顯是,進入“是”分支,即 this 指向 np;
2)那麼 this.x=1,即 np.x=1;
Point(2,2)函式在 var p= Point(2,2)中的 this 在 "JavaScript this 決策樹"中進行判定的過程是這樣的:
1)var p= Point(2,2)呼叫是用 new 進行呼叫的麼?這個明顯不是,進入“否”分支,即函式是否用 dot(.)進行呼叫?;
2)Point(2,2)函式不是用 dot(.)進行呼叫的?判定為否,即進入“否”分支,即這裡的 this 指向全域性變數 window,那麼 this.x 實際上就是 window.x;
3)this.x=2 即 window.x=2.
最後看一下函式用 call 和 apply 進行呼叫的例子:
functionPoint(x,y){
this.x=x;
this.y=y;
this.moveTo=function(x,y){
this.x=x;
this.y=y;
}
}
varp1=newPoint(0,0);
varp2={x:0,y:0};
p1.moveTo.apply(p2,[10,10]);//apply實際上為p2.moveTo(10,10)
p2.x//10
p1.moveTo.apply(p2,[10,10])函式在 "JavaScript this決策樹"中進行判定的過程是這樣的:
我們知道,apply 和 call 這兩個方法異常強大,他們允許切換函式執行的上下文環境(context),即 this 繫結的物件。p1.moveTo.apply(p2,[10,10])實際上是p2.moveTo(10,10)。那麼 p2.moveTo(10,10)可解釋為:
1) p2.moveTo(10,10)函式呼叫是用 new 進行呼叫的麼?這個明顯不是,進入“否”分支,即函式是否用 dot(.)進行呼叫?
2)p2.moveTo(10,10)函式是用 dot(.)進行呼叫的,即進入“是”分支,即這裡的this 指向 p2.moveTo(10,10)中.之前的物件 p2,所以 p2.x=10;
例項:
varname="Thewindow";
varobj={
name:'myobject',
getNameFunc:function(){
alert(this.name);
returnfunction(){
alert(this.name);
}
}
}
obj.getNameFunc()();
關於 JavaScript 函式執行環境的過程,IBM developerworks 文件庫中的一段描述感覺很不錯,摘抄如下:
“ JavaScript 中的函式既可以被當作普通函式執行,也可以作為物件的方法執行,這是導致 this 含義如此豐富的主要原因。一個函式被執行時,會建立一個執行環境(ExecutionContext),函式的所有的行為均發生在此執行環境中,構建該執行環境時,JavaScript 首先會建立 arguments 變數,其中包含呼叫函式時傳入的引數。接下來建立作用域鏈。然後初始化變數,首先初始化函式的形參表,值為 arguments 變數中對應的值,如果 arguments 變數中沒有對應值,則該形參初始化為 undefined。如果該函式中含有內部函式,則初始化這些內部函式。如果沒有,繼續初始化該函式內定義的區域性變數,需要注意的是此時這些變數初始化為 undefined,其賦值操作在執行環境(ExecutionContext)建立成功後,函式執行時才會執行,這點對於我們理解 JavaScript中的變數作用域非常重要,鑑於篇幅,我們先不在這裡討論這個話題。最後為 this 變數賦值,如前所述,會根據函式呼叫方式的不同,賦給 this 全域性物件,當前物件等。至此函式的執行環境(ExecutionContext)建立成功,函式開始逐行執行,所需變數均從之前構建好的執行環境(ExecutionContext)中讀取。”
理解這段話對於理解 Javascript 函式將大有好處!