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

全部開發(fā)者教程

JavaScript 入門教程

JavaScript 函數(shù)

在 JavaScript中,函數(shù)是頭等 (first-class) 對(duì)象,因?yàn)樗鼈兛梢韵袢魏纹渌麑?duì)象一樣具有屬性和方法。它們與其他對(duì)象的區(qū)別在于函數(shù)可以被調(diào)用。簡(jiǎn)而言之,它們是 Function 對(duì)象。(MDN)

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

1. 函數(shù)的使用

1.1 語法

函數(shù)使用前通常與變量一樣需要先進(jìn)行聲明,用 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í)候傳遞過去的,在函數(shù)執(zhí)行過程中可以訪問到
  • 函數(shù)執(zhí)行完畢后可以有一個(gè)返回值,調(diào)用函數(shù)的地方可以接收到這個(gè)返回值

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

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

以下是一個(gè)最簡(jiǎn)單的函數(shù):

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

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

調(diào)用這個(gè)函數(shù)就會(huì)在控制臺(tái)輸出 hello 字符串。

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

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

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

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

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

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

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í)可以傳遞值過去,這些值可以在函數(shù)中被訪問。

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

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

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

最終變量 perimeter 也會(huì)被賦值為12。

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

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

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

比如如下代碼塊:

// 改寫前
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);

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

// 改寫后
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ù)名可以很容易的了解到這一段代碼作用是用來判斷一個(gè)數(shù)是否為質(zhì)數(shù)。

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

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

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

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

2.2.1 拼寫準(zhǔn)確

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

當(dāng)然許多時(shí)候手一快可能就少了一個(gè)字母,或者錯(cuò)將 wrap 進(jìn)行乾坤大挪移拼寫成了 warp

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

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

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

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

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

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

function jslsh() {}

function jsNumber() {}

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

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

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

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

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

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

2.2.4 合理使用縮寫

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

如:

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

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

3. 函數(shù)示例

3.1 計(jì)算圓的面積

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

function circleArea(r) {
    var pi = 3.1415926;

    return pi * r * r;
}

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

3.2 判斷某個(gè)DOM元素是否含有某個(gè)類名

分析:

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

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

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

function hasClass(el, className) {
  // el 是 element的縮寫,表示一個(gè)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ù)的其他知識(shí)

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

4.1 函數(shù)表達(dá)式

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

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

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

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

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

光看句子有點(diǎn)抽象,舉個(gè)例子?:

var num1 = add1(1, 2);

var num2 = add2(3, 4);

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

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

上面一段代碼在執(zhí)行的時(shí)候會(huì)報(bào) add2 is not a function 的錯(cuò)誤,表示 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í)行以上代碼會(huì)報(bào) b is not defined 錯(cuò)誤。

4.3 匿名函數(shù)

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

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

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

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

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

如:

(function() {
    var num = 1;

    alert(num);
})();

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

以下這段代碼會(huì)報(bào)錯(cuò):

// 報(bào)錯(cuò)
function() {
    var num = 1;

    alert(num);
}();

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

通過括號(hào)包裹一段函數(shù),讓js引擎識(shí)別成他是一個(gè)函數(shù)表達(dá)式,再對(duì)他進(jìn)行執(zhí)行,就不會(huì)報(bào)錯(cuò),這是加括號(hào)的原因。

同理,可以使用 +,! 等運(yùn)算符代替括號(hào),讓一個(gè)匿名函數(shù)成為一個(gè)函數(shù)表達(dá)式即可。

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

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

函數(shù)表達(dá)式進(jìn)行聲明的時(shí)候也可以使用具名函數(shù)

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

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

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

    return fn(num - 1) + num;
}

count(5);

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

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

4.5 arguments

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

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

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

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

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

sum(1, 2, 3, 4);

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

如,一個(gè)不確定用戶輸入的參數(shù)個(gè)數(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 對(duì)象,就可以得到所有參數(shù),然后做累加就可以達(dá)到求和的目的。

4.6 函數(shù)和方法

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

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

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

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

4.7 JS DOC 注釋

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

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

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

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

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

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

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

純函數(shù)只負(fù)責(zé)輸入輸出,對(duì)于一種輸入只有一種函數(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)一個(gè)函數(shù)與 new 關(guān)鍵字一起被調(diào)用的時(shí)候,就會(huì)作為一個(gè)構(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)用的時(shí)候,默認(rèn)返回的是一個(gè)對(duì)象。

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

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

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

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

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

5. 小結(jié)

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

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