函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別
聲明一個(gè)函數(shù)有三種方式
1.用function聲明一個(gè)函數(shù):
2.函數(shù)表達(dá)式方法:
3.function構(gòu)造函數(shù)的方法(一般不使用):
因?yàn)樽兞刻嵘脑蛎删撸瘮?shù)表達(dá)式的方法提升的是var print球榆,所以用function聲明的函數(shù)在執(zhí)行時(shí),會(huì)把函數(shù)提升到j(luò)s語(yǔ)句的頂部禁筏,所以即使函數(shù)調(diào)用出現(xiàn)在函數(shù)聲明的前面持钉,也不會(huì)出現(xiàn)報(bào)錯(cuò);而用函數(shù)表達(dá)式的方法聲明的函數(shù)提升的是var定義的變量篱昔,所以會(huì)報(bào)錯(cuò)每强。
什么是變量的聲明前置始腾?什么是函數(shù)的聲明前置
JS語(yǔ)言的特性是JS引擎在解析JS代碼時(shí)會(huì)先獲取所有被聲明的變量然后再一行一行的運(yùn)行,所以所有var聲明的變量和function聲明的函數(shù)會(huì)前置到代碼頭部空执,所以使用或調(diào)用在其后的變量或函數(shù)也不會(huì)報(bào)錯(cuò)
arguments 是什么
arguments是一個(gè)類數(shù)組對(duì)象浪箭,對(duì)應(yīng)于傳遞給函數(shù)的參數(shù),可以通過(guò)索引的方式訪問(wèn)函數(shù)傳入的參數(shù)辨绊,arguments[i]奶栖,i為數(shù)組中元素的索引
函數(shù)的"重載"怎樣實(shí)現(xiàn)
JS里因?yàn)橥瘮?shù)會(huì)被覆蓋所以沒(méi)有重載,但是可以在函數(shù)體針對(duì)不同的參數(shù)調(diào)用執(zhí)行相應(yīng)的邏輯(模擬重載)
注意:傳參時(shí)需注意傳入?yún)?shù)的順序
立即執(zhí)行函數(shù)表達(dá)式是什么门坷?有什么作用
立即執(zhí)行函數(shù)的作用是隔離作用域宣鄙,使被執(zhí)行的函數(shù)內(nèi)部的變量不會(huì)污染到外部,即外部不能訪問(wèn)函數(shù)內(nèi)部的變量默蚌。寫(xiě)法:
(function fn(){})()
[function fn(){}]()
!function fn(){}()
求n!冻晤,用遞歸來(lái)實(shí)現(xiàn)
打印結(jié)果:
寫(xiě)一個(gè)函數(shù),返回參數(shù)的平方和绸吸?
如下代碼的輸出鼻弧?為什么
console.log(a);
var a = 1;
console.log(b);
因?yàn)槁暶髑爸茫陨厦娲a等價(jià)于:
var a
console.log(a);
a = 1;
console.log(b);
所以console.log(a)輸出 undefined
console.log(b)輸出b is not defined
如下代碼的輸出锦茁?為什么
sayName('world');
sayAge(10);
function sayName(name){
console.log('hello ', name);
}
var sayAge = function(age){
console.log(age);
};
聲明前置所以代碼等價(jià)于:
function sayName(name){
console.log('hello ', name);
}
var sayAge
sayName('world');
sayAge(10);
sayAge = function(age){
console.log(age);
};
所以sayName('world');輸出 hello world
sayAge(10);輸出 sayAge is not a function
如下代碼輸出什么? 寫(xiě)出作用域鏈查找過(guò)程偽代碼
var x = 10
bar()
function foo() {
console.log(x)
}
function bar(){
var x = 30
foo()
}
偽代碼:
1.globalContext = {
AO: {
x: 10
foo: function(){}
bar: function(){}
}
Scope: null
}
// 聲明 foo 時(shí) 得到下面
foo.[[scope]] = globalContext.AO
bar.[[scope]] = globalContext.AO
//調(diào)用bar()時(shí) 進(jìn)入bar()的執(zhí)行上下文
2. barContext={
AO: {
x:30
}
bar.[[scope]] = globalContext.AO
}
//調(diào)用foo()時(shí) 進(jìn)入foo()的執(zhí)行上下文
3. fooContext={
AO:{ }
foo.[[scope]] = globalContext.AO
}
foo( )的x是globalContext的x 所以輸出10
如下代碼輸出什么? 寫(xiě)出作用域鏈查找過(guò)程偽代碼
var x = 10;
bar()
function bar(){
var x = 30;
function foo(){
console.log(x)
}
foo();
}
偽代碼:
1.globalContext = {
AO: {
x: 10
bar: function(){}
}
Scope: null
}
// 聲明 bar 時(shí) 得到下面
bar.[[scope]] = globalContext.AO
2. barContext = {
AO: {
x: 30,
foo: function
},
Scope: bar.[[scope]] //globalContext.AO
}
foo.[[scope]] = barContext.AO
3. fooContext = {
AO: {},
Scope: foo.[[scope]] // barContext.AO
}
調(diào)用foo( )時(shí)先在foo的AO里找温数,找不到再去bar的AO里找 所以輸出30
如下代碼輸出什么? 寫(xiě)出作用域鏈查找過(guò)程偽代碼
var x = 10;
bar()
function bar(){
var x = 30;
(function (){
console.log(x)
})()
}
執(zhí)行過(guò)程同上一題但是bar內(nèi)嵌套的是一個(gè)立即執(zhí)行函數(shù)聲明以后立即調(diào)用并執(zhí)行自身同時(shí)其內(nèi)部沒(méi)有x變量所以會(huì)去bar的AO里找所以輸出 30
如下代碼輸出什么? 寫(xiě)出作用域鏈查找過(guò)程偽代碼
var a = 1;
function fn(){
console.log(a)
var a = 5
console.log(a)
a++
var a
fn3()
fn2()
console.log(a)
function fn2(){
console.log(a)
a = 20
}
}
function fn3(){
console.log(a)
a = 200
}
fn()
console.log(a)
聲明前置后:
var a = 1;
function fn(){
var a
console.log(a)
a = 5
console.log(a)
a++
fn3()
fn2()
console.log(a)
function fn2(){
console.log(a)
a = 20
}
}
function fn3(){
console.log(a)
a = 200
}
執(zhí)行過(guò)程如下:調(diào)用fn( )后進(jìn)入其執(zhí)行上下文,首先var a但未賦值所以打印undefined后 a=5所以打印5蜻势,a++此時(shí)fn內(nèi)部a為6,調(diào)用fn3時(shí)進(jìn)入fn3的執(zhí)行上下文首先打印1后a=200污染了全局變量a鹉胖,執(zhí)行完退出調(diào)用fn2進(jìn)入fn2的執(zhí)行上下文打印6握玛,執(zhí)行a=20污染了fn內(nèi)部的變量a所以打印出20最后在打印200