首頁 > web前端 > js教程 > JavaScript函數的4種呼叫方法詳解_javascript技巧

JavaScript函數的4種呼叫方法詳解_javascript技巧

WBOY
發布: 2016-05-16 16:51:44
原創
1099 人瀏覽過

在JavaScript中,函數是一等公民,函數在JavaScript中是一個資料類型,而非像C#或其他描述性語言那樣僅僅作為一個模組來使用。函數有四種呼叫模式,分別是:函數呼叫形式、方法呼叫形式、建構器形式、以及apply形式。這裡所有的呼叫模式中,最主要的差異在於關鍵字 this 的意義,以下分別介紹這個幾種呼叫形式。

本文主要內容:

1.分析函數的四種呼叫形式
2.弄清楚函數中this的意義
3.明確建構函物件的過程
4.學會使用上下文呼叫函數

一、函數呼叫形式

函數呼叫形式是最常見的形式,也是最好理解的形式。所謂函數形式就是一般宣告函數後直接呼叫即是。例如:

複製程式碼 程式碼如下:

// 宣告一個函數,並呼叫


// 宣告一個函數,並呼叫
function func() {
    alert("Hello World");
}
func();
或:或:



複製程式碼

程式碼如下:

// 使用函數的Lambda表達式定義函數,然後呼叫
var func = function() {

alert("你好,程式設計師");};func();這兩段程式碼都會在瀏覽器中彈出一個對話框,顯示字串中的文字,這個就是函數呼叫。 可以發現函數呼叫很簡單,就是平常學習的一樣,這裡的關鍵是,在函數呼叫模式中,函數裡的 this 關鍵字指全域對象,如果在瀏覽器中就是 window 對象。例如:



複製程式碼

程式碼如下:

var func = function() {

var func = function() {
alert(this);


函數呼叫模式很簡單,是最基本的呼叫方式。但是同樣的是函數,將其賦值給一個物件的成員以後,就不一樣了。將函數賦值給物件的成員後,那麼這個就不在稱為函數,而應該叫做方法。例如:




複製程式碼


程式碼如下:


// 定義一個函數
= function() {    alert("我是一個函數麼?");};// 賦值給一個物件var o = {};o. fn = func; // 注意這裡不要加圓括號// 呼叫
o.fn();

此時,o.fn 則是方法,不是函數了。實際上 fn 的方法體與 func 是一模一樣的,但這裡有個微妙的不同。看下面的程式碼:


複製程式碼


程式碼如下:


// 接上上面的程式碼
alert(o.fn === func);
列印結果是true,這表示兩個函數是一樣的東西,但修改一下函數的程式碼:

// 修改函數體
var func = function() {    alert(this);

};

var o = {};

o.fn = func;var o = {};o.fn = func;

// 比較

alert(o.fn === func);
// 呼叫

func();o.fn();這裡的運行結果是,兩個函數是相同的,因此列印結果是true。但由於兩個函數的調用是不一樣的,func 的調用,打印的是 [object Window],而 o.fn 的打印結果是 [object Object]。 這裡便是函數呼叫與方法呼叫的區別,函數呼叫中,this 專指全域物件 window,而在方法中 this 專指目前對象,即 o.fn 中的 this 指的就是物件o。
三、構造器呼叫模式 同樣是函數,在單純的函數模式下,this 表示 window;在物件方法模式下,this 指的是目前物件。除了這兩種情況,JavaScript 中函數還可以是建構器。將函數當作建構器來使用的語法就是在函式呼叫前面加上一個 new 關鍵字。如程式碼:複製程式碼 程式碼如下:

// 定義一個建構子
var Person = function() {
    this.name = "程式設計師";
    this.sayHello = function() {
    this.sayHello = function() {
    this.sayHello = function() { "你好,這裡是" this.name);
    };
};
// 呼叫建構器,建立物件
var p = new Person();
// 使用物件
p.sayHello();
上面的案例先建立一個建構函式Person,然後再使用建構子建立物件p。這裡使用 new 語法。然後在使用物件呼叫sayHello()方法,這個使用建構函式創建物件的案例比較簡單。從案例可以看到,此時 this 指的是物件本身。除了上面簡單的使用以外,函數作為建構器還有幾個變化,分別為:

1、所有需要物件使用的屬性,必須使用 this 引導;

2、函數的 return 語句意義被改寫,如果傳回非對象,就回傳this。

構造器中的 this


我們需要分析創建物件的過程,方能知道 this 的意義。如下面程式碼:

程式碼如下:

var Person = function() {
    this.name = "程式設計師";
};
var p = new Person();

這裡先定義了函數Person,以下分析整個執行:

1、程式在執行到這句話的時候,不會執行函數體,因此 JavaScript 的解釋器並不知道這個函數的內容。

2、接下來執行 new 關鍵字,創建對象,解釋器開闢內存,得到對象的引用,將新對象的引用交給函數。

3、緊接著執行函數,將傳過來的物件參考交給 this。也就是說,在建構方法中,this 就是剛被 new 建立出來的物件。

4、然後為 this 新增成員,也就是為物件新增成員。

5、最後函數結束,回傳 this,將 this 交給左邊的變數。

分析過建構子的執行以後,可以得到,建構子中的 this 就是目前物件。

構造器中的 return

在建構函式中 return 的意義發生了變化,首先如果在建構函式中,如果傳回的是一個對象,那麼就保留原意。如果傳回的是非對象,例如數字、布林和字串,那就回傳this,如果沒有return 語句,那麼也回傳this,看下面程式碼:

複製程式碼 程式碼如下:

// 回傳一個物件的return
var ctr = function() {
    this.name = " ctr = function() {
    this.name = "f曉虎叫🎜>    return {
        name:"牛亮亮"
    };
};
// 建立物件
var psvar. >alert(p.name);

執行程式碼,這裡印出來的結果是」牛亮亮」。因為構造方法中回傳的是一個對象,保留return 的意義,回傳內容為return 後面的對象,再看下面程式碼:


複製程式碼 程式碼如下:
// 定義傳回非物件資料的建構器
var ctr = function() {
    this.name = "趙虎曉";
    this.name = "趙虎曉";
    return "牛亮亮";
};
// 建立物件
var p = new ctr();
// 使用
alert(p);
alert(p. name);
代碼運行結果是,先彈窗打印[object Object],然後打印”趙曉虎”,因為這裡return 的是一個字符串,屬於基本類型,那麼這裡的return 語句無效,返回的是this 對象,因此第一個印製的是[object Object]而第二個不會印出undefined。

四、apply呼叫模式

除了上述三種呼叫模式以外,函數作為物件還有 apply 方法與 call 方法可以使用,這便是第四種呼叫模式,我稱之為 apply 模式。

先介紹 apply 模式,首先這裡 apply 模式既可以像函數一樣使用,也可以像方法一樣使用,可以說是一個靈活的使用方法。首先來看語法:函數名稱.apply(物件, 參數陣列);

這裡看文法比較晦澀,還是使用案例來說明:

1、新建兩個 js 文件,分別為”js1.js”與”js2.js”;

2、新增程式碼


複製程式碼 程式碼如下:

// js1.js 檔案中
var func1 = function() {
    this.name = "程式設計師";
};
func1.apply(null);
alert(name);

// js2.js 檔案
var func2 = function() {
    this.name = "程式設計師";
};
var o = {};
func2. apply(o);
alert(o.name);

3、分別運行著兩段程式碼,可以發現第一個檔案中的name 屬性已經載入到全域物件window 中;而第二個檔案中的name 屬性是在傳入的物件o 中,也就是第一個相當於函數調用,第二個相當於方法調用。

這裡的參數是方法本身所帶的參數,但是需要用陣列的形式儲存在,例如程式碼:

複製程式碼 程式碼如下:

// 一個陣列的例子
var arr1 = [1,2,3,[4,5],[6,7,8]];
// 將其展開
var arr2 = arr1.conact.apply([], arr1);
然後介紹一下call 模式,call 模式與apply 模式最大的不同在於call 中的參數不用數組,看下面程式碼就清楚了:

// 定義方法
var func = function(name, age, sex) {
    this.name = name;
    this.age = age;
 🎜>};
// 建立物件
var o = {};
// 為物件新增成員
// apply 模式
var p1 = func.apply(o, ["趙曉虎", 19, "男"]);
// call 模式
var p2 = func.call(o, "趙曉虎", 19, "男");

上面的程式碼,apply 模式與 call 模式的結果是一樣的。

實際上,使用 apply 模式和 call 模式,可以任意的操作控制 this 的意義,在函數 js 的設 計模式中使用廣泛。簡單小結一下,js 中的函數呼叫有四種模式,分別是:函數式、方法式、建構器式和apply 式. 而這些模式中,this 的意義分別為:在函數中this 是全域物件window,在方法中this 指當前對象,在建構函數中this 是被創建的對象,在apply 模式中this 可以隨意的指定.。在 apply 模式中如果使用 null,就是函數模式,如果使用對象,就是方法模式。

五、綜合例子

下面透過一個案例結束本篇吧。案例說明:有一個div,id為dv,滑鼠移到上面去高度增大2倍,滑鼠離開恢復,下面直接上js程式碼:


複製程式碼 程式碼如下:

var dv = document.getElementById("dv");
var height = parseInt(dv.style.height || dv.offsetHeight);
var intervalIduse = function() {
    // 停止已執行的動畫
    clearInterval(intervalId);
    // 得到目標高度
    var toHeight
    var that = this;
    // 開器計時器,緩慢變化
    intervalId = setInterval(function() {        // 記錄每次需要變化的步長
        var h = Math.ceil(Math.abs(height - toHeight) / 110判斷變化,如果步長為0就停止計時器
        if( h > 0 ) {
           h) "px";
        } else {
            clearInterval(intervalId); } dv.onmouseout = function() {
    / / 原則與之前相同
    clearInterval(intervalId);
    var toHeight = height;
    var that = this;
  height = parseInt(dv. style.height || dv.offsetHeight);
        var h = Math.ceil(Math.abs(height - toHeight) / 10);
   that.style.height = (height - h) "px";
        } else {
             ;


相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板