函數(shù)與作用域

1.函數(shù)聲明和函數(shù)表達式有什么區(qū)別

function命令聲明的代碼區(qū)塊,就是一個函數(shù)。function命令后面是函數(shù)名,函數(shù)名后面是一對圓括號,里面是傳入函數(shù)的參數(shù)。函數(shù)體放在大括號里面。

function print(s) {
  console.log(s);
}```
除了用function命令聲明函數(shù),還可以采用變量賦值的寫法。

var print = function(s) {
console.log(s);
};```
這種寫法將一個匿名函數(shù)賦值給變量。這時,這個匿名函數(shù)又稱函數(shù)表達式(Function Expression),因為賦值語句的等號右側(cè)只能放表達式。
函數(shù)的表達式需要在語句的結(jié)尾加上分號,表示語句結(jié)束。而函數(shù)的聲明在結(jié)尾的大括號后面不用加分號。

區(qū)別:

函數(shù)聲明:聲明不必放到調(diào)用的前面
函數(shù)表達式:聲明必須放到調(diào)用的前面

JavaScript 解釋器中存在一種變量聲明被提升(hoisting)的機制,也就是說變量(函數(shù))的聲明會被提升到作用域的最前面,即使寫代碼的時候是寫在最后面,也還是會被提升至最前面。
例如以下代碼段:

alert(foo); // function foo() {}
alert(bar); // undefined
function foo() {}
var bar = function bar_fn() {};
alert(foo); // function foo() {}
alert(bar); // function bar_fn() {}```
輸出結(jié)果分別是function foo() {}、undefined、function foo() {}和function bar_fn() {}。
可以看到 foo 的聲明是寫在 alert 之后,仍然可以被正確調(diào)用,因為 JavaScript 解釋器會將其提升到 alert 前面,而以函數(shù)表達式創(chuàng)建的函數(shù) bar 則不享受此待遇。

# 2.什么是變量的聲明前置?什么是函數(shù)的聲明前置
在一個作用域下,var 聲明的變量和function 聲明的函數(shù)會前置
與全局作用域一樣,函數(shù)作用域內(nèi)部也會產(chǎn)生“變量提升”現(xiàn)象。var命令聲明的變量,不管在什么位置,變量聲明都會被提升到函數(shù)體的頭部。
# 3.arguments 是什么
由于JavaScript允許函數(shù)有不定數(shù)目的參數(shù),所以我們需要一種機制,可以在函數(shù)體內(nèi)部讀取所有參數(shù)。這就是arguments對象的由來。

arguments對象包含了函數(shù)運行時的所有參數(shù),arguments[0]就是第一個參數(shù),arguments[1]就是第二個參數(shù),以此類推。這個對象只有在函數(shù)體內(nèi)部,才可以使用。
# 4.函數(shù)的"重載"怎樣實現(xiàn)
>函數(shù)重載(英語:Function overloading),是Ada、C++、C#、D和Java等編程語言中具有的一項特性,這項特性允許創(chuàng)建數(shù)項名稱相同但功能的輸入輸出類型不同的子程序,它可以簡單地稱為一個單獨功能可以執(zhí)行多項任務(wù)的能力。

其他語言重載范例

int sum(int num1, int num2){
return num1 + num2;
}

float sum(float num1, float num2){
return num1 + num2;
}

sum(1, 2);
sum(1.5, 2.4);

Javascript中,先定義的函數(shù),會被后定義的函數(shù)覆蓋。因此Javascript不支持函數(shù)的重載,不能夠定義同樣的函數(shù)然后通過編譯器去根據(jù)不同的參數(shù)執(zhí)行不同的函數(shù)。

但是javascript卻可以通過自身屬性去模擬函數(shù)重載。
變相實現(xiàn)函數(shù)重載的方法:
- 利用arguments對象

<script type="text/javascript">
function showSum()
{
//使用arguments對象模擬出重載效果
if (arguments.length == 1)
{
alert(arguments[0] + 1);
}
else if (arguments.length == 2)
{
alert(arguments[0] + arguments[1]);
}
else if (arguments.length == 3)
{
alert(arguments[0] + arguments[1] + arguments[2]);
}
else {
alert('請傳入?yún)?shù)!');
}
}
//顯示101
showSum(100);
//顯示200
showSum(100, 100);
//顯示300
showSum(100, 100,100);
</script>```

5.立即執(zhí)行函數(shù)表達式是什么?有什么作用

立即執(zhí)行函數(shù)就是
1.聲明一個匿名函數(shù)
2.馬上調(diào)用這個匿名函數(shù)

JavaScript引擎規(guī)定,如果function關(guān)鍵字出現(xiàn)在行首,一律解釋成語句,為了兼容 JS 的語法。避免瀏覽器報語法錯誤,可以這樣寫:
(function(){alert('我是匿名函數(shù)')} ()) // 用括號把整個表達式包起來
(function(){alert('我是匿名函數(shù)')}) () //用括號把函數(shù)包起來
!function(){alert('我是匿名函數(shù)')}() // 求反,我們不在意值是多少,只想通過語法檢查。
+function(){alert('我是匿名函數(shù)')}()
-function(){alert('我是匿名函數(shù)')}()
~function(){alert('我是匿名函數(shù)')}()
void function(){alert('我是匿名函數(shù)')}()
new function(){alert('我是匿名函數(shù)')}()

只有一個作用:創(chuàng)建一個獨立的作用域。
這個作用域里面的變量,外面訪問不到(即避免「變量污染」)。
參考文章:https://zhuanlan.zhihu.com/p/22465092

6.求n!,用遞歸來實現(xiàn)

function factor(n){
  if(n === 1) {
    return 1;
  }
  return n * factor(n-1);
}

factor(5);

注意:求遞歸的時候要考慮負數(shù)和0;

7.以下代碼輸出什么?

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('男');
 name: 饑人谷
 age: 2
 sex: 男
 ["饑人谷", 2, "男", callee: function, Symbol(Symbol.iterator): function]
 name valley

 name: 小谷
 age: 3
 sex: undefined
 ["小谷", 3, callee: function, Symbol(Symbol.iterator): function]
 name valley

 name: 男
 age: undefined
 sex: undefined
 ["男", callee: function, Symbol(Symbol.iterator): function]
 name valley

8 寫一個函數(shù),返回參數(shù)的平方和?

 function sumOfSquares(){
var sum = 0;
   for (var i = 0; i<arguments.length; i++) {
       sum = sum+arguments[i]*arguments[i];
}
    return sum;
   }
   var result = sumOfSquares(2,3,4)
   var result2 = sumOfSquares(1,3)
   console.log(result) 
   console.log(result2)

9 如下代碼的輸出?為什么

    console.log(a);//undefined;變量a被提升
    var a = 1;
    console.log(b);//Uncaught ReferenceError: b is not defined;b未聲明

10. 如下代碼的輸出?為什么

sayName('world');
sayAge(10);
function sayName(name){
    console.log('hello ', name);//hello world;函數(shù)聲明被提升到代碼最前面。
}
var sayAge = function(age){
    console.log(age);//Uncaught TypeError: sayAge is not a function;這是函數(shù)表達式,只有var sayAge被提升到代碼前面;
};

11. 如下代碼輸出什么? 寫出作用域鏈查找過程偽代碼

var x = 10
bar() 
function foo() {
  console.log(x)//10;
}
function bar(){
  var x = 30
  foo()
}

函數(shù)本身也是一個值,也有自己的作用域。它的作用域與變量一樣,就是其聲明時所在的作用域,與其運行時所在的作用域無關(guān)。總之,函數(shù)執(zhí)行時所在的作用域,是定義時的作用域,而不是調(diào)用時所在的作用域。

globalContext = {
  AO: {
    x: 10
    foo: function
    bar: function
  },
  Scope: null
}

barContext= {
AO: {
     x:30
   }
scope:globalContext.AO
}

fooContex= {
AO: {}
scope:globalContext.AO
}

12. 如下代碼輸出什么? 寫出作用域鏈查找過程偽代碼

var x = 10;
bar() 
function bar(){
  var x = 30;
  function foo(){
    console.log(x) //30
  }
  foo();
}   ```

globalContext = {
AO: {
x: 10
bar: function
},
Scope: null
}

barContext= {
AO: {
x:30
foo: function
}
scope:globalContext.AO
}

fooContex= {
AO: {}
scope:barContext.AO
}

# 13. 以下代碼輸出什么? 寫出作用域鏈的查找過程偽代碼

var x = 10;
bar()
function bar(){
var x = 30;
(function (){
console.log(x)//30
})()
}```

globalContext = {
  AO: {
    x: 10
    bar: function
  },
  Scope: null
}

barContext= {
AO: {
     x:30
   }
scope:globalContext.AO
}

fooContex= {
AO: {}
scope:barContext.AO
}

立即執(zhí)行函數(shù)的作用域鏈 與普通函數(shù)作用域鏈一樣.(要說區(qū)別,立即不會提升)

14. 以下代碼輸出什么? 寫出作用域鏈查找過程偽代碼

var a = 1;

function fn(){
  console.log(a)//undefined
  var a = 5
  console.log(a)//5
  a++
  var a
  fn3()
  fn2()
  console.log(a)//20

  function fn2(){
    console.log(a)//6
    a = 20
  }
}

function fn3(){
  console.log(a)//1
  a = 200
}

fn()
console.log(a)//200
globalContext = {
  AO: {
    a: 1
    fn: function
    fn3: function
  },
  Scope: null
}

fnContext= {
AO: {
     a:5
     fn2: function
   }
scope:globalContext.AO
}

fn2Contex= {
AO: {}
scope:fnContext.AO
}

fn3Contex= {
AO: {}
scope:globalContext.AO
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 函數(shù)聲明和函數(shù)表達式有什么區(qū)別 JavaScript 中需要創(chuàng)建函數(shù)的話,有兩種方法:函數(shù)聲明、函數(shù)表達式,各自寫...
    蕭雪圣閱讀 1,030評論 2 2
  • 函數(shù)聲明和函數(shù)表達式有什么區(qū)別 函數(shù)聲明:function fn(){}; 函數(shù)表達式: var fn = fun...
    cross_王閱讀 295評論 0 0
  • 1.函數(shù)聲明和函數(shù)表達式有什么區(qū)別 函數(shù)聲明:function functionName(){};使用functi...
    saintkl閱讀 245評論 0 0
  • 1. 函數(shù)聲明和函數(shù)表達式有什么區(qū)別 使用function關(guān)鍵字聲明一個函數(shù)時,聲明不必放到調(diào)用的前面。//函數(shù)聲...
    _李祺閱讀 329評論 0 0
  • 原來音樂中也有核心素養(yǎng),要想唱好歌必須要有音色的支撐!我在思考問題音樂課對學(xué)生應(yīng)該如何去評價?它對一個人的成長影響...
    心中有善閱讀 192評論 0 0

友情鏈接更多精彩內(nèi)容