第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

全部開發(fā)者教程

JavaScript 入門教程

JavaScript 函數(shù)

在 JavaScript中,函數(shù)是頭等 (first-class) 對象,因為它們可以像任何其他對象一樣具有屬性和方法。它們與其他對象的區(qū)別在于函數(shù)可以被調(diào)用。簡而言之,它們是 Function 對象。(MDN)

函數(shù)就是一段代碼片段,調(diào)用函數(shù)就是執(zhí)行函數(shù)中的代碼。

1. 函數(shù)的使用

1.1 語法

函數(shù)使用前通常與變量一樣需要先進行聲明,用 function 關(guān)鍵字定義函數(shù)。

// 常見的函數(shù)的定義方式
function 函數(shù)名(參數(shù)1, 參數(shù)2, ...) {
  代碼片段;

  return 返回值;
}

// 調(diào)用函數(shù) (執(zhí)行函數(shù)中的代碼)
var 函數(shù)的返回值 = 函數(shù)名(參數(shù)1, 參數(shù)2, ...);
  • 調(diào)用函數(shù)就是執(zhí)行函數(shù)中的代碼
  • 參數(shù)是調(diào)用函數(shù)的時候傳遞過去的,在函數(shù)執(zhí)行過程中可以訪問到
  • 函數(shù)執(zhí)行完畢后可以有一個返回值,調(diào)用函數(shù)的地方可以接收到這個返回值

1.2 調(diào)用函數(shù)

使用 函數(shù)名() 的方式即可調(diào)用一個函數(shù)

以下是一個最簡單的函數(shù):

function say() {
  console.log('hello');
}

say(); // 輸出:"hello"

調(diào)用這個函數(shù)就會在控制臺輸出 hello 字符串。

這個函數(shù)沒有返回值,默認(rèn)會返回一個 undefined。

1.3 帶有參數(shù)與返回值的函數(shù)

在聲明函數(shù)的時候,可以對參數(shù)也做上說明

假設(shè)有一個需求,需要一個計算三角形周長的函數(shù)。

計算三角形周長則需要知道三角形三條邊各自的長度,然后將他們求和。

定義函數(shù)的時候就可以將三條邊作為參數(shù)進行聲明。

function calcPerimeter(a, b, c) {
  // a, b, c 分別代表三條邊
  var sum = a + b + c;

  return sum;
}

// 調(diào)用函數(shù) 并將返回值賦值給perimeter
var perimeter = calcPerimeter(3, 4, 5);

在調(diào)用函數(shù)的時可以傳遞值過去,這些值可以在函數(shù)中被訪問。

在以上 calcPerimeter 函數(shù)被調(diào)用的時,傳遞了 3, 4, 5 三個值。

三個值對應(yīng)到函數(shù)聲明時定義的三個參數(shù) a, b, c。

所以函數(shù)執(zhí)行過程中 sum 的值為 3 + 4 + 5,即 12,隨后 sum 被作為返回值進行返回。

最終變量 perimeter 也會被賦值為12。

2. 怎么運用函數(shù)

2.1 合理包裝內(nèi)容

函數(shù)可以對代碼進行封裝,讓邏輯更加清晰。

比如如下代碼塊:

// 改寫前
var num = 10;

var flag = false;

var i;
var len;
for (i = 2, len = num - 1; i <= len; i++) {
    if (num % i === 0) {
        flag = true;
        break;
    }
}

console.log(flag);

以上代碼第一眼可能無法看出具體在做什么,僅需要做一點修改,就能有所改善。

// 改寫后
function isPrimeNumber(num) {
  var flag = false;
  
  var i;
  var len;
  for (i = 2, len = num - 1; i <= len; i++) {
    if (num % i === 0) {
      flag = true;
      break;
    }
  }

  return flag;
}


var num = 10;

var result = isPrimeNumber(num);

console.log(result);

改寫后的代碼似乎多了幾行,但是將其中核心部分包裝成了函數(shù)。

通過 isPrimeNumber 函數(shù)名可以很容易的了解到這一段代碼作用是用來判斷一個數(shù)是否為質(zhì)數(shù)

當(dāng)然有個前提就是起一個 可以讓大部分人看得懂 的函數(shù)名。

2.2 優(yōu)秀的函數(shù)名

優(yōu)秀的函數(shù)名可以幫助他人更容易理解代碼,同時當(dāng)自己一段時間后再回頭看代碼時,能更容易進入當(dāng)時寫代碼時候的思維模式等。

這里提供幾個函數(shù)命名的建議,具體的命名可以根據(jù)團隊規(guī)范、個人成長等做調(diào)整。

2.2.1 拼寫準(zhǔn)確

準(zhǔn)確的拼寫十分重要,絕大多數(shù)情況下函數(shù)名都會是英文單詞組成的。

當(dāng)然許多時候手一快可能就少了一個字母,或者錯將 wrap 進行乾坤大挪移拼寫成了 warp。

許多情況是無法避免的,經(jīng)常需要自檢。

當(dāng)然可以借助一些單詞的檢查插件,如 Visual Studio Code 可以借助 Code Spell Checker 插件來檢查單詞的正確性。

再者碰到想起的函數(shù)名但是單詞拼寫不出來,盡可能翻詞典,日積月累能有大量的詞匯沉淀。

2.2.2 盡量不使用拼音或者混用拼寫

盡量不要使用拼音或者是首字母縮寫。

以下函數(shù)名或許會造成困擾:

function jslsh() {}

function jsNumber() {}

以上是計算兩數(shù)和函數(shù)的命名,可能只有天和地知道這個是什么意思。

當(dāng)然,如果是自己寫 demo 或者測試代碼的時候,其實不需要考慮這么多。

2.2.3 有“狀態(tài)”的函數(shù)名

如碰到函數(shù)功能是判斷是否、有沒有、可以的時候,可以帶上一些前綴,比如:

// 是否登入
function isLogin() {}

同時可以合理的使用動詞,比如打開文件就可以使用 openFile 函數(shù)名,具體的狀態(tài)可以根據(jù)語境、函數(shù)作用、個人習(xí)慣等做調(diào)整使用。

2.2.4 合理使用縮寫

使用詞語的縮寫盡量使用通用的縮寫

如:

  • pwd - password
  • mgr - manager
  • del - delete

這些縮寫大部分開發(fā)者是可以看的懂的縮寫。

3. 函數(shù)示例

3.1 計算圓的面積

分析:根據(jù)圓面積公式 S=π·r·r,其中 S 就是要求的值,即函數(shù)的返回值,π 是常量(固定的一個值),半徑r是未知數(shù),所以r就可以設(shè)計成參數(shù)

function circleArea(r) {
    var pi = 3.1415926;

    return pi * r * r;
}

// 計算半徑為10的圓的面積
var area = circleArea(10);

3.2 判斷某個DOM元素是否含有某個類名

分析:

某個DOM某個類名可以說明有兩個未知量,可以設(shè)計成兩個參數(shù)。

根據(jù)描述也可以確定一個 某個DOM 的類型是個 DOM 對象,某個類名是個字符串

只要拿到這個DOM的 class 屬性,判斷里面是不是含有這個類型即可得到結(jié)果

function hasClass(el, className) {
  // el 是 element的縮寫,表示一個dom元素
  
  // 如果沒有元素 則返回
  if (!el) {
      return false;
  }

  // 根據(jù)空格分割成數(shù)組
  // 可以不使用 split 方法,使用字符串也可以用indexOf匹配
  var classList = el.className.split(' ');

  // 判斷是否存在
  if (classList.indexOf(className) >= 0) {
      return true;
  }
  
  return false;
}

4. 函數(shù)的其他知識

以下擴展內(nèi)容可能需要一定的知識積累,遇到不懂的地方可以停下腳步,先學(xué)習(xí)下一章節(jié)

4.1 函數(shù)表達式

以上篇幅的函數(shù)其實都通過函數(shù)聲明的方式來定義,還有一種方式就是使用函數(shù)表達式定義函數(shù)。

// 函數(shù)聲明
function add(a, b) {
    return a + b;
}

// 函數(shù)表達式
var add = function(a, b) {
    return a + b;
};

通過上述例子可以看出寫法上的區(qū)別就是函數(shù)表達式是將函數(shù)賦值給了變量。

這兩種方式創(chuàng)建的函數(shù)最大的區(qū)別在于,不能提前調(diào)用使用函數(shù)表達式創(chuàng)建的函數(shù)

光看句子有點抽象,舉個例子?:

var num1 = add1(1, 2);

var num2 = add2(3, 4);

// 函數(shù)聲明
function add1(a, b) {
    return a + b;
}

// 函數(shù)表達式
var add2 = function(a, b) {
    return a + b;
};

上面一段代碼在執(zhí)行的時候會報 add2 is not a function 的錯誤,表示 add2 不是函數(shù),也就是說 add2 不能被提前使用,而 add1 可以。

具體原因可以查看執(zhí)行上下文章節(jié)。

4.2 函數(shù)作用域

函數(shù)有他自己的作用域,函數(shù)內(nèi)聲明的變量等通常情況下不能被外部訪問,但是函數(shù)可以訪問到外部的變量或者其他函數(shù)等

var a = 1;

function fn() {
    var b = 2;

    console.log(a); // 輸出:1
    console.log(b); // 輸出:2
}

fn();

console.log(b); // ReferenceError: b is not defined

執(zhí)行以上代碼會報 b is not defined 錯誤。

4.3 匿名函數(shù)

沒有名字的函數(shù)就是一個匿名函數(shù)

var fn = function() {
    console.log('我是一個匿名函數(shù)');
};

除了在函數(shù)表達式中會出現(xiàn)匿名函數(shù),還有許多場景。

相對常見的一個就是自執(zhí)行匿名函數(shù),MDN官方翻譯為立即調(diào)用函數(shù)表達式

自執(zhí)行就是這個函數(shù)聲明后就會立即執(zhí)行,自執(zhí)行的匿名函數(shù)通常會被用來形成獨立的作用域。

如:

(function() {
    var num = 1;

    alert(num);
})();

這是一個自執(zhí)行的匿名函數(shù),這個匿名函數(shù)是被包裹了一段括號后才被調(diào)用的。

以下這段代碼會報錯:

// 報錯
function() {
    var num = 1;

    alert(num);
}();

瀏覽器會告訴你必須給函數(shù)一個名字。

通過括號包裹一段函數(shù),讓js引擎識別成他是一個函數(shù)表達式,再對他進行執(zhí)行,就不會報錯,這是加括號的原因。

同理,可以使用 +,! 等運算符代替括號,讓一個匿名函數(shù)成為一個函數(shù)表達式即可。

大部分第三方框架都會通過一個自執(zhí)行的匿名函數(shù)包裹代碼,與瀏覽器全局環(huán)境隔離,避免污染到全局環(huán)境。

4.4 具有函數(shù)名的函數(shù)表達式

函數(shù)表達式進行聲明的時候也可以使用具名函數(shù)

var count = function fn(num) {
    console.log('我是一個函數(shù)');
};

以上這段代碼是不會報錯的,但是不能通過 fn 訪問到函數(shù),這里的 fn 只能在函數(shù)內(nèi)部進行訪問,通常在使用遞歸的形式做計算的時候會用到這種寫法。

var count = function fn(num) {
    if (num < 0) {
        return num;
    }

    return fn(num - 1) + num;
}

count(5);

上面這個例子,就是在函數(shù)內(nèi)部訪問 fn 調(diào)用自己,使用遞歸的形式求和。

注:遞歸相關(guān)的知識可以參考相關(guān)文獻進行學(xué)習(xí)

4.5 arguments

arguments 是一個對應(yīng)于傳遞給函數(shù)的參數(shù)的類數(shù)組對象。(MDN)

通常情況下函數(shù)都具有 arguments 對象,可以在函數(shù)內(nèi)部直接訪問到。

他是一個類數(shù)組,即長得很像數(shù)組,成員都是用數(shù)字編號,同時具有 length 屬性。

arguments 中存放著當(dāng)前函數(shù)被調(diào)用時,傳遞過來的所有參數(shù),即便不聲明參數(shù),也可以通過 arguments 取到傳遞過來的參數(shù)。

function sum() {
    console.log(arguments);
}

sum(1, 2, 3, 4);

執(zhí)行上述代碼,可以看到在控制臺輸出了一個對象,存放的就是所有傳遞過去的參數(shù),利用這一特性,就可以不限制參數(shù)個數(shù),或者讓函數(shù)做中轉(zhuǎn)站(攔截函數(shù)),利用 arguments 將參數(shù)傳遞給另一個函數(shù)。

如,一個不確定用戶輸入的參數(shù)個數(shù)的求和函數(shù):

function sum() {
  var total = 0;

  var i;
  var len;
  for (i = 0, len = arguments.length; i < len; i++) {
    total += arguments[i];
  }

  return total;
}

var total = sum(1, 2, 3, 4, 15);
console.log(total); // 輸出:25

通過循環(huán)遍歷 arguments 對象,就可以得到所有參數(shù),然后做累加就可以達到求和的目的。

4.6 函數(shù)和方法

方法在本質(zhì)上是個函數(shù)。

通常都能聽到“調(diào)用一下某個方法”,“取到某個方法的返回值”,這里的方法其實就是一個函數(shù)。

一般方法是用來描述對象的某個行為的,但是平時我們會混用,口頭交流的時候會經(jīng)常把函數(shù)直接稱作方法。

只要自己理解,不需要去糾結(jié)函數(shù)和方法到底是什么,也不用特意糾正別人的說法,大家都能聽得懂就行。

4.7 JS DOC 注釋

使用 JS DOC 描述函數(shù)是非常良好的習(xí)慣,良好的 JS DOC 書寫還可以使用工具快速生成文檔。

JS DOC 對函數(shù)的描述大體如下:

/**
 * 這是這個求冪函數(shù) 計算 x 的 y 次方
 * @param {Number} x - 底數(shù)
 * @param {String} y - 指數(shù)
 */
function pow(x, y) {
    // ...
}

除此之外還可以描述返回值等。

4.8 純函數(shù)與副作用

所謂純函數(shù),就是沒有副作用的函數(shù)

一個函數(shù)從執(zhí)行開始到結(jié)束,沒有對外部環(huán)境做任何操作,即對外部環(huán)境沒有任何影響(沒有副作用),這樣的函數(shù)就是純函數(shù)。

純函數(shù)只負(fù)責(zé)輸入輸出,對于一種輸入只有一種函數(shù)返回值。

如果函數(shù)中存在 Math.random 這種影響返回值的函數(shù),也不能算是純函數(shù)。

// 純函數(shù)
function add(a, b) {
  return a + b;
}

// 非純函數(shù)
var person = { name: '小明' };
function changeName {
  person.name = '小紅'; // 影響了函數(shù)外的內(nèi)容,產(chǎn)生了副作用
}

4.9 構(gòu)造函數(shù)

當(dāng)一個函數(shù)與 new 關(guān)鍵字一起被調(diào)用的時候,就會作為一個構(gòu)造函數(shù)。

function Person(name, age) {
    this.name = name;
    this.age = age;
}

Person.prototype.say = function() {
    console.log('我是' + this.name);
};

var person = new Person('阿梅', 12);

person.say();

console.log(person);

可以看到當(dāng)函數(shù)作為構(gòu)造函數(shù)調(diào)用的時候,默認(rèn)返回的是一個對象。

細(xì)心的讀者仔細(xì)觀察就能發(fā)現(xiàn),構(gòu)造函數(shù)的默認(rèn)返回值是函數(shù)體內(nèi)的 this。

事實上構(gòu)造函數(shù)的執(zhí)行有一定流程:

  1. 創(chuàng)建一個空對象,將函數(shù)的this指向這個空對象
  2. 執(zhí)行函數(shù)
  3. 如果函數(shù)沒有指定返回值,則直接返回 this(一開始創(chuàng)建的空對象),否則返回指定返回值

理解這個流程,就能理解構(gòu)造函數(shù)的返回值。

具體的函數(shù)的 prototype 屬性等可以參閱原型章節(jié)。

5. 小結(jié)

函數(shù)特性相對較多,也是 JavaScript 的核心之一。

函數(shù)可以用于封裝代碼,提供代碼的復(fù)用率和可讀性,在大部分情況下,當(dāng)兩段代碼具有超高相似度時,應(yīng)當(dāng)設(shè)計成函數(shù),不同的部分使用參數(shù)進行區(qū)分。