深刻挖掘js之函數

前言: 前端這兩年的新技術鋪天蓋地,各類框架、工具層出不窮眼花繚亂。最近打算好好複習下 js 基礎,夯實的基礎纔是學習新技術的基石。本文做爲讀書筆記簡單的總結下 js 函數的基礎知識。前端


1、函數對象

  • JavaScript中的函數就是對象。對象是「名/值」對的集合並擁有一個鏈接到原型對象的隱藏鏈接。對象字面量產生的對象鏈接到Object.prototype。函數對象鏈接到Function.prototype(該原型對象自己鏈接到Object.prototype)。
  • 每一個函數對象在建立時也會有一個prototype屬性。它的值是一個擁有constructor屬性且值即爲該函數的對象。
  • 函數是對象,能夠保存在變量、對象和數組中。函數能夠當作參數傳遞給其餘函數,函數也能夠在返回函數,函數擁有方法。

2、函數字面量

函數對象經過函數字面量來建立:數組

var add = function(a,b){
return a+b;
};

函數字面量包括四個部分:閉包

  • 1 保留字function
  • 2 函數名(可省略)
  • 3 包圍在括號中的一組參數,在函數被調用是初始化爲實際的參數的值
  • 4 包圍在花括號裏的一組語句塊

注意:一個內部函數除了能夠訪問本身的參數和變量,同時也能夠自由的訪問父函數的參數和變量。用過這種函數字面量建立的函數對象包含一個鏈接到外部上下文的鏈接。這個被稱爲閉包app

3、函數調用

  • 每一個函數接收兩個附加的參數:this和arguments(實際參數),在JavaScript中有四種調用方式:方法調用模式,函數調用模式,構造器調用模式和apply調用模式

方法調用模式

當有個函數被保存爲對象的一個屬性是,咱們稱他爲一個方法。當以個方法被調用時,this被綁定到該對像。框架

var myObject = {
    value: 0,
    increment: function (icn) {
        this.value += typeof inc === 'number' ? icn: 1;
    }
}
myObject.increment();
console.log(myObject.value);

myObject.increment(2);
console.log(myObject.value);

方法可使用this訪問本身所屬的對象。經過this可取可取的他們所屬對象的上下文的方法稱爲公共方法異步

函數調用模式

  • 當一個函數並不是一個對象的屬性時,那麼它就是被當作一個函數來調用的,以此模式調用函數,this被綁定到了全局對象。這是錯誤的,正確的設計應該是當內部函數被調用時,this應該綁定到外部函數的this變量。所以聲明一個that變量並賦值this,內部函數就能夠經過that訪問到this。這個聽起來比較難理解,咱們以代碼的形式來講明
myObject.double = function(){
    var that = this ;
    var helper = function(){
        that .value = add(that.value,that.value);
    }
    helper(); //以函數的形式調用helper
}
//以方法的形式調用double
myObject.double();
console.log(myObject.value);

構造器調用模式

  • JavaScript是基於原型繼承的語言,對象能夠直接從其餘對象繼屬性,該語言是無類型的。
  • 若是在一個函數前面帶上new來調用,name背地裏就會建立一個鏈接到該函數的prototype成員的新對象,同時this會綁定到新對象上
//建立一個構造器函數Quo
var Quo = function(string){
    this.status = string;
};
//給Quo提供一個get_status的公共方法
Quo.prototype.get_status = function(){
    return this.status;
};
//構造一個Quo實例
var myQuo = new Quo("hello world");
console.log(myQuo.get_status());

Apply 調用模式

  • apply方法能夠構建一個參數數組傳遞給調用函數,apply方法接收兩個數組,第一個是要綁定給this的值,第二個就是一個參數數組。
var array = [3,4];
var sum = add.apply(null,array);
var statusObject = {
    status: 'A-ok'
};
 var status = Quo.prototype.get_status.apply(statusObject);
 console.log(status); //A-OK

參數

  • 當函數被調用時會獲得arguments數組,函數能夠經過此參數訪問全部被它調用時傳遞的參數列表
arguments並非一個真正的數組,擁有一個length屬性,但它沒有任何數組的方法

返回

  • 若是函數調用時在前面加一個new前綴,且返回值不是一個對象,則返回this

4、函數做用域

  • 咱們已經知道,在代碼外部添加包裝函數將內部的變量和函數定義「隱藏」起來,外部做用域沒法訪問包裝函數內部的任何東西 例如:
var a = 2;
function foo(){
var a =3;
consloe.log(a);//3
}
foo();
consloe.log(a);//2

閉包

  • 內部函數能夠訪問定義在他們外部的函數的變量和參數(除了this、arguments)
var que = function(status){
    return {
        get_status: function(){
            return status;
        }
    }
}
var myQuo = que("hello");
console.log(myQuo.get_status());

get_status方法並非訪問參數的副本,他訪問的就是參數的自己,這就是閉包,保護status爲私有屬性函數

回調callBack()

  • 1 搞清異步和同步
function a(){
    console.log('執行a函數');
    setTimeout(function(){
        console.log("執性a函數的延遲函數")
    },1000)
};
function b (){
    console.log('執行函數b')
}
a();
b();

以上代碼會先執行函數a,並且不會等到a中的延遲函數執行完才執行函數b, 在延遲函數被觸發的過程當中就執行了函數b,當js引擎的event 隊列空閒時纔會去執行隊列裏等待的setTimeout的回調函數,這就是一個異步的例子工具

  • 2回調函數究竟是什麼

如下是谷歌得出的結論學習

callback is a function that is passed as an argument to another function and is executed after its parent function has completed.

模塊

  • 咱們可使用函數和閉包來構造模塊,模塊是一個提供個藉口卻隱藏狀態與實現的函數或對象
  • 模塊模式利用函數做用域和閉包來建立被綁定對象與私有成員的關聯
  • 模塊的通常形式:一個定義了私有變量和函數的函數;利用閉包建立能夠訪問私有變量和函數的特權,最後一個返回該特權函數,或者把它們保存在一個能夠訪問的到的地方
模塊模式須要具有兩個條件
  • 一、必須有外部的封裝函數,該函數必須至少被調用一次(每次調用都會建立一個新的模塊實例)。
  • 二、封閉函數必須返回至少一個尼日不函數,這樣內部函數才能在私有的做用域造成閉包,而且能夠訪問或者能夠修改私有狀態。
var foo= (function(){
    var something = 'cool';
    var another =[1,2,3];
    function doSomething(){
        console.log(something);
    }
    function doAnother(){
        console.log(another.join(' ! '));
    }
    return{
        doSomething: doSomething,
        doAnother: doAnother
    }
})();
foo.doSomething();
foo.doAnother();
相關文章
相關標籤/搜索