函數(shù)聲明和函數(shù)表達式有什么區(qū)別
- 函數(shù)聲明
使用function關(guān)鍵字聲明一個函數(shù)
function sayHello {
console.log('hello')
}
- 函數(shù)表達式
var sayHello = function (){
console.log('hello')
}
- 使用函數(shù)表達式來聲明函數(shù)時,聲明必須寫在調(diào)用的前面;他們的作用域鏈不相同,函數(shù)表達式是全局作用域
什么是變量的聲明前置?什么是函數(shù)的聲明前置
代碼在電腦中編譯的過程是:
1.先檢測整段代碼中變量的聲明和函數(shù)聲明語句,執(zhí)行這些語句
2.然后按照從上到的順序執(zhí)行函數(shù)調(diào)用語句或其他語句
3.最后執(zhí)行變量的賦值
上述過程中,第一步叫做變量和函數(shù)的聲明前置
arguments 是什么
arguments對象用于獲取到該函數(shù)的所有傳入?yún)?shù),arguments對象是所有函數(shù)中可用的局部變量。可以使用arguments對象在函數(shù)中引用函數(shù)的參數(shù)。此對象包含傳遞給函數(shù)的每個參數(shù)的條目,第一個條目的索引從0開始。
函數(shù)的"重載"怎樣實現(xiàn)
function printPeopleInfo(name, age, sex){
if(name){
console.log(name);
}
if(age){
console.log(age);
}
if(sex){
console.log(sex);
}
}
printPeopleInfo('Byron', 26);
printPeopleInfo('Byron', 26, 'male');
立即執(zhí)行函數(shù)表達式是什么?有什么作用
- 立即執(zhí)行函數(shù)可以在函數(shù)聲明的同時立即執(zhí)行,從而隔離作用域,防止函數(shù)內(nèi)變量污染全局
(function(){
var a = 1;
})()
console.log(a); //undefined
其他寫法
(function fn1() {} ());
// 在數(shù)組初始化器內(nèi)只能是表達式
[function fn2() {} ()];
// 逗號也只能操作表達式
1, function fn3() {} ();
!function fn4() {} ();
(function fn5() {}) ();
求n!,用遞歸來實現(xiàn)
function factor(n){
if(n === 1) {
return 1
}else if(n === 0){
return 1
}
return n * factor(n-1)
}
以下代碼輸出什么?
function getInfo(name, age, sex){
console.log('name:',name);
console.log('age:', age);
console.log('sex:', sex);
console.log(arguments);
arguments[0] = 'valley';
console.log('name', name);
}
getInfo('饑人谷', 2, '男');
getInfo('小谷', 3);
getInfo('男');
輸出:
getInfo('饑人谷', 2, '男');
getInfo('小谷', 3);
getInfo('男');
name: 饑人谷
age: 2
sex: 男
(3) ["饑人谷", 2, "男", callee: function, Symbol(Symbol.iterator): function]
name valley
name: 小谷
age: 3
sex: undefined
(2) ["小谷", 3, callee: function, Symbol(Symbol.iterator): function]
name valley
name: 男
age: undefined
sex: undefined
["男", callee: function, Symbol(Symbol.iterator): function]
name valley
寫一個函數(shù),返回參數(shù)的平方和?
function sumOfSquares(){
for(i = 0; i < arguments.length; i++) {
sum += arguments[i] * arguments[i];
}
}
var result = sumOfSquares(2,3,4)
var result2 = sumOfSquares(1,3)
console.log(result) //29
console.log(result2) //10
如下代碼的輸出?為什么
console.log(a);//‘undefind’,在輸出之前 a未被賦值
var a = 1;
console.log(b);//‘Uncaught ReferenceError: b is not defined’,變量b沒有被聲明
如下代碼的輸出?為什么
sayName('world');
sayAge(10);
function sayName(name){
console.log('hello ', name);
}
var sayAge = function(age){
console.log(age);
};
輸出:
hello world
Uncaught TypeError: sayAge is not a function//函數(shù)表達式不會像函數(shù)聲明一樣
被前置,所以執(zhí)行到sayAge(10);這一句時函數(shù)sayAge未被聲明,此時它還不是一個函數(shù)
如下代碼輸出什么? 寫出作用域鏈查找過程偽代碼
var x = 10
bar()
function foo() {
console.log(x)
}
function bar(){
var x = 30
foo()
}
輸出
10
作用域鏈查找過程偽代碼:
globalContext = {
AO:{
x:10
foo:function
bar:function
}
Scope:null
}
foo.[[scope]] = globalContext.AO
bar.[[scope]] = globalContext.AO
barContext = {
AO: {
x:30
}
Scope:bar.[[scope]] = globalContext.AO
}
fooContext = {
AO:{}
Scope:foo.[[scope]] = globalContext.AO
}
如下代碼輸出什么? 寫出作用域鏈查找過程偽代碼
var x = 10;
bar()
function bar(){
var x = 30;
function foo(){
console.log(x)
}
foo();
}
輸出:
30
作用域鏈查找過程偽代碼:
globalContext = {
AO:{
x:10
bar:function
}
Scope:null
}
bar.[[scope]] = globalContext.AO
barContext = {
AO:{
x:30
foo:function
}
Scope:bar.[[scope]] = globalContext.AO
}
foo.[[scope]] = barComtext.AO
fooContext = {
AO:{}
Scope:foo.[[scope]] = barComtext.AO
}
以下代碼輸出什么? 寫出作用域鏈的查找過程偽代碼
var x = 10;
bar()
function bar(){
var x = 30;
(function (){
console.log(x)
})()
}
輸出:
30
作用域鏈的查找過程偽代碼
globalContext = {
AO:{
x:10
bar:function
}
Scope:null
}
bar.[[scope]] = globalContext.AO
barContext = {
AO:{
x:30
funciton
}
Scope:bar.[[scope]] = globalContext.AO
}
function.[[scope]] = barContext.AO
functionContext = {
AO:{}
Scope:function.[[scope]] = barContext.AO
}
以下代碼輸出什么? 寫出作用域鏈查找過程偽代碼
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)
輸出:
undefine
5
1
6
20
200
作用域鏈查找過程偽代碼:
globalContext = {
AO:{
a:1
fn:function
fn3:function
}
Scope:null
}
fn.[[scope]] = globalContext.AO
fnContext = {
AO:{
a:undefind
fn3:function
fn2:function
}
Scope:globalContext.AO
}
fn3.[[scope]] = fnContext.AO
fn2.[[scope]] = fnContext.AO
console.log(a)/*在a聲明之前打印,undefind*/
fnContext = {
AO:{
a:5
fn3:function
fn2:function
}
Scope:globalContext.AO
}
fn3.[[scope]] = fnContext.AO
fn2.[[scope]] = fnContext.AO
console.log(a)/*在fn的AO內(nèi)找a的值,此時a已被賦值5,輸出5*/
fn3Context = {
AO:{
a:undefined
Scope:globalContext.AO
}
}
console.log(a)/*在fn3的AO內(nèi)找a的值,此時a未被聲明,于是在全局Context的AO內(nèi)找
a的值,此時a已被賦值1,輸出1*/
fn2Context = {
a:undefined
Scope:fnContext.AO
}
console.log(a)/*在fn2的AO內(nèi)找a的值,此時a未被聲明,于是在fn的AO中找a的值,此時
a為6,輸出6*/
console.log(a)/*在fn2的AO內(nèi)找a的值,此時a已被賦值20,輸出20*/
console.log(a)/*a被賦值200,輸出200*/