JS函式知識點梳理

源自世界發表於2019-03-03

要想學好JavaScript除了基本的JavaScript知識點外,作為JavaScript的第一等公民——函式,我們要深入的瞭解。函式的多變來源於引數的靈活多變和返回值的多變。如果引數是一般的資料型別或一般物件,這樣的函式就是普通函式;如果函式的引數是函式,這就是我們所要知道的高階函式;如果建立的函式呼叫另外一部分(變數和引數已經預置),這樣的函式就是偏函式。

此外,還有一點就是可選引數(optional parameter)的使用。

函式的分類

  1. 普通函式

有函式名,引數,返回值,同名覆蓋。示例程式碼如下:

function add(a, b) {
    return a + b;
}
複製程式碼
  1. 匿名函式

沒有函式名,可以把函式賦值給變數和函式,或者作為回撥函式使用。非常特殊的就是立即執行函式和閉包。

立即執行函式示例程式碼如下:

(function(){
    console.log(1)
})()
複製程式碼

閉包示例程式碼如下:

var func = (function() {
    var i = 1;
    return function() {
        console.log(i);
    }
})()
複製程式碼
  1. 高階函式

高階函式就是可以把函式作為引數和返回值的函式。如上面的閉包。ECMAScript中也提供大量的高階函式如forEach(), every(), some(), reduce()等等。

  1. 偏函式
function isType(type) {
    return function(obj) {
        return toString.call(obj) === "[object " + type + "]"
    }
}

var isString = isType(`String`);
var isFunction = isType(`Function`);
複製程式碼

相信,研究過vue.js等常見庫原始碼的同學不會陌生吧。

  1. 箭頭函式

箭頭函式不繫結自己的this,arguments,super。所以它不適合做方法函式,建構函式,也不適合用call,apply改變this。但它的特點就是更短,和解決匿名函式中this指向全域性作用域的問題

window.name = `window`;
var robot = {
    name: `qq`,
    print: function() {
        setTimeout(function() {
            console.log(this.name);
        }, 300)
    } 
};
// 修改1,用bind修改this指向
var robot = {
    name: `qq`,
    print: function() {
        setTimeout(function() {
            console.log(this.name);
        }.bind(this), 300)
    } 
};
// 修改2,使用箭頭函式
var robot = {
    name: `qq`,
    print: function() {
        setTimeout(() => {
            console.log(this.name);
        }, 300)
    } 
};
複製程式碼

想了解更多箭頭函式可以看MDN

函式的引數

  1. 傳入明確的引數
function add(a, b) {

    reutrn a + b;
}
複製程式碼
  1. 使用arguments物件
function add() {
    var argv = Array.prototype.slice.apply(arguments);
    return argv.length > 0 ? argv.reduce(function(acc, v) { return acc+=v}): ``;
}
複製程式碼
  1. 省略引數,引數預設值
function sub(a, b) {
    a = a || 0;
    b = b || 0;
    return a - b;
}
複製程式碼
  1. 物件引數
var option = {
    width: 10,
    height: 10
}

function area(opt) {
    this.width = opt.width || 1;
    this.height = opt.height || 1;
    return this.width * this.height
}
複製程式碼

物件引數比較常見,常出現在jQuery外掛,vue外掛等中。

  1. 可選引數

ES5實現可選引數,我們需要使用arguments。使用指定範圍的可選引數我們一般使用發物件引數,寫過jQuery等外掛的應該印象深刻。

  1. ES6中的函式引數

在ES6中,引數預設值,省略引數操作使用比較簡便。示例程式碼如下:

var area = (width=1, height=1) => width*height
複製程式碼

在ES6中,使用可選引數。示例程式碼如下:

var add = (...nums) => {
    var numArr = [].concat(nums)
    return numArr.reduce((acc, v) => acc += v)
}
複製程式碼
  1. 解構引數
myFunc = function({x = 5,y = 8,z = 13} = {x:1,y:2,z:3}) {
    console.log(x,y,z);
};

myFunc(); //1 2 3  (預設值為物件字面量)
myFunc({}); //5 8 13   (預設值為物件本身)
複製程式碼

函式的返回值

  1. 函式的返回值為基本資料型別,如字串,數字,Boolean,null,undefined。示例程式碼如下:
function add(a, b) {
    return a + b
}
複製程式碼
  1. 函式的返回值為物件。示例程式碼如下:
function Robot(name) {
    this.name = name
}

Robot.prototype.init = function() {
    return {
        say: function () {
            console.log(`My name is ` + this.name)
        }.bind(this),
        dance:  function(danceName) {
            console.log(`My dance name is ` + danceName)
        }
    };
}

var robotA = new Robot(`A`);
robotA.init().say(); // "My name is A"
var robotB = new Robot(`B`);
robotB.init().say(); // "My name is B"
複製程式碼

不管是寫原生還是jQuery外掛,亦或其他外掛,這種情況都不少見。更深入的瞭解可以參考jQuery原始碼。

  1. 返回值為函式

這個我們最為熟悉的莫過於閉包。具體可參考
老生常談之閉包

參考文章

JS: How can you accept optional parameters?

Named and Optional Arguments in JavaScript

How to use optional arguments in functions (with optional callback)

後續可能還會繼續修改,也歡迎各位批評指正。有問題或者有其他想法的可以在我的GitHub上pr。

相關文章