函數(shù)是 JavaScript 中的基本組件之一。 一個(gè)函數(shù)是 JavaScript 過程 — 一組執(zhí)行任務(wù)或計(jì)算值的語句。要使用一個(gè)函數(shù),你必須將其定義在你希望調(diào)用它的作用域內(nèi)。一個(gè)JavaScript 函數(shù)用function關(guān)鍵字定義,后面跟著函數(shù)名和圓括號(hào)。
函數(shù)上下文:當(dāng)瀏覽器首次載入你的腳本,它將默認(rèn)進(jìn)入全局執(zhí)行上下文。如果,你在你的全局代碼中調(diào)用一個(gè)函數(shù),你程序的時(shí)序?qū)⑦M(jìn)入被調(diào)用的函數(shù),并創(chuàng)建一個(gè)新的執(zhí)行上下文,并將新創(chuàng)建的上下文壓入執(zhí)行棧的頂部。
如果你調(diào)用當(dāng)前函數(shù)內(nèi)部的其他函數(shù),相同的事情會(huì)在此上演。代碼的執(zhí)行流程進(jìn)入內(nèi)部函數(shù),創(chuàng)建一個(gè)新的執(zhí)行上下文并把它壓入執(zhí)行棧的頂部。瀏覽器總會(huì)執(zhí)行位于棧頂?shù)膱?zhí)行上下文,一旦當(dāng)前上下文函數(shù)執(zhí)行結(jié)束,它將被從棧頂彈出,并將上下文控制權(quán)交給當(dāng)前的棧。這樣,堆棧中的上下文就會(huì)被依次執(zhí)行并且彈出堆棧,直到回到全局的上下文。
在JavaScript中,可以簡(jiǎn)單的認(rèn)為this就是函數(shù)的上下文,
- 函數(shù)直接用
()調(diào)用,this指向window對(duì)象
function fun() {
var a = 666;
console.log(this.a);
}
var a = 6;
fun()
- 函數(shù)作為一個(gè)對(duì)象
obj的方法,由對(duì)象調(diào)用obj.function(),this指向這個(gè)對(duì)象obj
function fun() {
var a = 666;
console.log(this.a);
}
var obj = {
"a" : 10,
"b" : 20,
"c" : fun,
}
obj.c()
- 函數(shù)是事件處理函數(shù),由事件觸發(fā)調(diào)用,this指向這個(gè)事件對(duì)象
function fun() {
this.style.background = red;
}
var box = document.getElementById("box");
box.onclick = fun;
- 函數(shù)由定時(shí)器調(diào)用,this指向window對(duì)象
var box = document.getElementById("box");
box.onclick = function(){
var self = this
setTimeout(function () {
self.style.background = red;
},2000)
};
- 數(shù)組中存放的函數(shù),由數(shù)組索引調(diào)用,this指向這個(gè)數(shù)據(jù)對(duì)象
var arr = [
{"a":10},
function fun() {
var a = 666;
console.log(`this.a: ${this.a}`);
console.log(`this.length: ${this.length}`);
},
"hi"
]
var a = 6;
arr[1]()
總結(jié):函數(shù)的上下文取決于函數(shù)
最終的調(diào)用形式,可以利用上面的五個(gè)規(guī)律做判斷
小測(cè)試1:
function fn(){
console.log(this.a);
}
var obj = {
"a" : 1,
"b" : [{
"a" : 3,
"b" : fn
}]
}
var a = 4;
obj.b[0].b()
最終調(diào)用形式為對(duì)象調(diào)用,符合規(guī)律2,提問:那個(gè)對(duì)象調(diào)用的?
小測(cè)試2:
function countArguments(a,b){
console.log(this.length);
}
arr = [countArguments,'123',10,'hi'];
arr[0](1,2,3)
最終調(diào)用形式為數(shù)組索引調(diào)用,符合規(guī)律5
小測(cè)試3:
var length = 10;
function fn(){
console.log(this.length);
}
var obj = {
length : 5,
method : function(fn) {
fn();
arguments[0]();
}
}
obj.method(fn);
提問1:有幾個(gè)結(jié)果?
提問2:結(jié)果代表的是什么?
答案:
會(huì)有
兩個(gè)結(jié)果
結(jié)果1是window對(duì)象的length
結(jié)果2是實(shí)參個(gè)數(shù)
腦洞測(cè)試1:
function fun2(a,b,c){
arguments[0](5,6,7,8);
}
function fun(m,n){
console.log(`this.length: ${this.length}`);
console.log(`arguments.length: ${arguments.length}`);
}
fun2(fun,6,7,8,9)
提問:誰是被執(zhí)行函數(shù)?
誰是調(diào)用函數(shù)?
腦洞測(cè)試2:
var number = 2;
var obj = {
number : 4,
fn1 : (function(){
this.number *= 2;
number *= 2;
var number = 3;
return function(){
this.number *= 2;
number *= 3;
console.log(number);
}
})(),
db2 : function(){
this.number *= 2;
}
};
var fn1 = obj.fn1;
console.log(number);
obj.fn1();
console.log(window.number);
console.log(obj.number);
2019/3/18