《javascript語言精粹》讀書筆記——函數

這幾天發現了一本好書,又薄又精闢,《JavaScript語言精粹》
看了對象、函數這兩節,發現書如其名,確實是精粹。

函數的調用

函數調用的方式有四種:
- 方法調用模式
- 函數調用模式
- 構造器調用模式
- apply調用模式

方法調用模式

這個方法是經常會見到的一種模式,方法作爲對象的一種屬性,通過obj.functionName()這種調用方式調用,如:

var myObject = {
    value: 0;
    increment: function(inc) {
        this.value += typeof inc === 'number' ? inc : 1; //默認增加爲1
    }
}
myObject.increment(); //方法調用模式
console.log(myObject.value); //1

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

方法調用的好處就是,this綁定的是調用該方法的對象,因此它可以訪問myObj.value

函數調用模式

當一個函數並非一個對象的屬性時,那麼它被當作一個函數來調用:

var sum=add(3,4)

當採用這種方式調用時,this被綁定到全局對象。

例如:

var a = 'gloabal:';

function test() {
    var a = 'add:';
    return (function() {
        return this.a + 1;
    })()
}
var sum = test();
console.log(sum);//global:1

按道理來講,test裏面的匿名函數應該訪問test的a,但是this卻指向了global;

如果聲明“use strict” ,會報異常:Cannot read property ‘a’ of undefined
作者說這是JavaScript語言設計上的錯誤。倘若語言設計正確,當內部函數被調用時,this應該仍然綁定到外部函數的this變量。

解決方法:

function add(a, b) {
    return a + b;
}
var myObject = {
    value: 1,
    getValue: function() {
        return this.value;
    }
}
myObject.double = function() {
    var that = this;
    var helper = function() {
        that.value = add(that.value, that.value);
    }
    helper(); //以函數方式調用helpher
}
myObject.double();
console.log(myObject.getValue()); //2

構造器調用模式

javascript是一門基於原型繼承的語言。這意味着對象可以直接從其他對象繼承屬性。
書中的例子:

var Quo = function(string) {
    this.status = string;
}
Quo.prototype.get_status = function(first_argument) {
    return this.status;
};

var myQuo = new Quo('Confused');
console.log(myQuo.get_status());

說明:
1、這裏聲明瞭一個Quo類
2、Quo具有屬性status,和原型方法get_status
3、因爲get_status是Quo的原型屬性,因此this指向調用Quo的對象

這種結合new前綴調用的函數,就被稱作是構造器函數了。
如果調用函數沒有在前面加上new,會發生非常糟糕的事情,既沒有編譯時的警告,也沒有運行時警告,所以大寫約定非常重要。

apply調用模式

javascrip是一門函數式的面向對象編程語言,所以函數可以擁有方法。
apply方法讓我們可以構建一個參數並用其去調用函數,它也允許我們選擇this的值,apply方法接收兩個參數。第一個是將被綁定給this的值,第二個是一個參數數組

var array = [3, 4];
var sum = add.apply(null, array);
/*延續demo3,利用apply,不需要new關鍵字,把對象statusObject通過apply傳遞*/
var statusObject = {
    status: 'A-OK'
};
var Quo = function(string) {
    this.status = string;
}
Quo.prototype.get_status = function(first_argument) {
    return this.status;
};
var status = Quo.prototype.get_status.apply(statusObject);
console.log(status);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章