成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

淺談細(xì)說 JS 函數(shù)(call,apply,重載)

U2FsdGVkX1x / 3204人閱讀

摘要:什么是函數(shù)引用的原話函數(shù)是一組可以隨時(shí)隨地運(yùn)行的語句。函數(shù)是由這樣的方式進(jìn)行聲明的關(guān)鍵字函數(shù)名一組參數(shù),以及置于括號(hào)中的待執(zhí)行代碼。

什么是函數(shù)?

引用 W3School 的原話:

函數(shù)是一組可以隨時(shí)隨地運(yùn)行的語句。
函數(shù)是 ECMAScript 的核心。
函數(shù)是由這樣的方式進(jìn)行聲明的:關(guān)鍵字 function、函數(shù)名、一組參數(shù),以及置于括號(hào)中的待執(zhí)行代碼。
函數(shù)的基本語法是這樣的:
function functionName(arg0, arg1, ... argN) {
  statements
}

聲明函數(shù)的幾種方式

調(diào)用函數(shù)的幾種方式

重載函數(shù)的實(shí)現(xiàn)

函數(shù)的獨(dú)立性

聲明函數(shù)

//聲明函數(shù)的4種方法

//方法一 直接聲明
function speak(word){
    console.log(word)
}

//方法二 指定一個(gè)匿名函數(shù) 將其賦給一個(gè)變量,后面可以直接通過該變量調(diào)用該函數(shù)
var speak2 = function (word) {
    console.log(word);
};//定義匿名函數(shù)需要注意最后需要加分號(hào)

//方法三 使用 Function對(duì)象 生成一個(gè)函數(shù)實(shí)例 
var speak3 = new Function("word","console.log(word);");

//方法四 使用 Function函數(shù) 返回函數(shù)實(shí)例
var speak4 = Function("word","console.log(word);");

調(diào)用函數(shù)基本方法

speak("hello world for global !");

this.speak("hello world for this !");

window.speak("hello world for window !");

調(diào)用函數(shù)的高級(jí)方法

speak.call(null,"hello world with call !");//null 代表是用全局對(duì)象 window 調(diào)用

speak.apply(null,["hello world with apply !"]);

輸出結(jié)果:

這里方法一大家不言而喻,簡單明了,直接就是聲明了一個(gè)函數(shù),需要指出的是,默認(rèn)寫的函數(shù)在不依附其他對(duì)象的情況下均為全局函數(shù),即成為 window 對(duì)象的成員,可以直接使用 window(Window 對(duì)象的實(shí)例,Window 對(duì)象實(shí)現(xiàn)了核心 JavaScript 所定義的所有全局屬性和方法)調(diào)用,或者通過 this 調(diào)用,在這里JS 頂層代碼中 this 指向的就是 window

每當(dāng)我們使用方法一聲明了一個(gè)函數(shù)的時(shí)候,實(shí)際是生成了一個(gè) Function 對(duì)象的實(shí)例.即每個(gè)函數(shù)其實(shí)質(zhì)都是一個(gè) Function 對(duì)象實(shí)例.

注意:
JS 解析器每解析到一個(gè)函數(shù)的時(shí)候,都會(huì)在堆內(nèi)存內(nèi)劃分出一塊空間來存儲(chǔ)創(chuàng)建該 Function 實(shí)例

方法二:
首先 JS 解析器解析到一個(gè)函數(shù)的時(shí)候,在堆內(nèi)存內(nèi)劃分出一塊空間來存儲(chǔ)創(chuàng)建該 Function 實(shí)例,接著在當(dāng)前棧內(nèi)存
創(chuàng)建一個(gè)叫 speak2 的變量,這個(gè)變量有個(gè)值,這個(gè)值是一個(gè)地址,指向的是堆內(nèi)存中的那個(gè) Function 實(shí)例.實(shí)際上這就是大名鼎鼎的引用.

方法三:
與方法一和方法二不同的是,前兩個(gè)方法都是聲明好讓解析器去解析,讓解析器生成 Function 實(shí)例(就是上面聲明的函數(shù),解析器調(diào)用 Function 構(gòu)造器來生成實(shí)例,這些步驟是我們看不到的),方法三是我們手動(dòng)調(diào)用 Function 構(gòu)造器生成 Function 實(shí)例(步驟掌握在自己的手里)

方法四:
與方法三不同的地方就是沒有 new,在這里 new 與沒 new 的區(qū)別就是當(dāng)有 new 的時(shí)候 Function 函數(shù)充當(dāng)一個(gè)構(gòu)造器,new 后返回的就是實(shí)例化后得到的對(duì)象(此時(shí)Function 內(nèi)部的 this指向的就是當(dāng)前生成的對(duì)象),不使用 new 的話就是把 Function 函數(shù)看做一個(gè)普通函數(shù)直接調(diào)用,直接調(diào)用 Function 函數(shù)讓其在內(nèi)部(我們看不到)new 一個(gè)實(shí)例返回,本質(zhì)是一樣的.

call方法與 apply 方法
查看EcmaScript.js

可以看到 call 方法與 apply 方法的區(qū)別:

他們的第一個(gè)參數(shù)指的是調(diào)用該方法對(duì)象

call 方法的第二個(gè)參數(shù)是可變數(shù)組參數(shù),即可以傳入多個(gè)參數(shù),非傳入一個(gè)數(shù)組.傳入的多個(gè)參數(shù)對(duì)應(yīng)的是被調(diào)用方法的各參數(shù).

apply 方法的第二個(gè)參數(shù)是一個(gè)數(shù)組對(duì)象,即可以直接傳入一個(gè)數(shù)組對(duì)象,數(shù)組對(duì)象的每項(xiàng)對(duì)應(yīng)的是被調(diào)用的方法的各參數(shù).

實(shí)現(xiàn)重載函數(shù)
在 JS 中,并不像其他強(qiáng)類型語言一樣可以聲明重載函數(shù),若在原先聲明的函數(shù)后再聲明一個(gè)不同參數(shù)數(shù)量的函數(shù)(JS是弱語言, 聲明的函數(shù)不需要指明參數(shù)類型),解析器會(huì)用后面聲明的函數(shù)覆蓋前面聲明的函數(shù).那我們?cè)撊绾螌?shí)現(xiàn)呢.

arguments 對(duì)象
在每個(gè)函數(shù)都有一個(gè)arguments 屬性,同樣查看 EcmaScript.js

當(dāng)生成一個(gè)函數(shù)實(shí)例后,解析器會(huì)賦給arguments 屬性一個(gè)Arguments對(duì)象實(shí)例,這個(gè)實(shí)例是什么,再看 EcmaScript.js

可以得知其為一個(gè)對(duì)象同時(shí)為數(shù)組對(duì)象的子類,故可以將其當(dāng)初數(shù)組對(duì)象使用.
函數(shù)實(shí)例中的 arguments對(duì)象(可以算是一個(gè)數(shù)組)的數(shù)組項(xiàng)內(nèi)容便是我們?cè)谡{(diào)用函數(shù)時(shí)進(jìn)行傳遞的參數(shù).只要我們有傳參,這個(gè)屬性就有數(shù)組項(xiàng),否則數(shù)組長度為0,故我們可以通過arguments.length 來查看其得到的形參的數(shù)量.

有了上面的基礎(chǔ)便可實(shí)現(xiàn)重載函數(shù)
這里引用 W3School 的例子

function doAdd() {
  if(arguments.length == 1) {
    alert(arguments[0] + 5);
  } else if(arguments.length == 2) {
    alert(arguments[0] + arguments[1]);
  }
}

doAdd(10);        //輸出 "15"
doAdd(40, 20);    //輸出 "60"

函數(shù)的獨(dú)立性
我們都知道,每當(dāng)我們聲明了一個(gè)函數(shù),其實(shí)際為一個(gè) Function 實(shí)例,那它獨(dú)立在哪呢,如何體現(xiàn)呢
看一下代碼:

function Dog(name,age){
    this.name = name;
    this.age = age;
    this.showName = function () {
        console.log(this.name);
    }
}

function Cat(name,age){
    this.name = name;
    this.age = age;
    this.showName = function () {
        console.log(this.name);
    }
}

var dog = new Dog("wangwang",2);
var cat = new Cat("miaomiao",3);

dog.showName();
cat.showName();
dog.showName.call(cat);

輸出結(jié)果為:

解釋:
每當(dāng)我們?cè)诤瘮?shù)內(nèi)使用 this 的時(shí)候,無非這幾種情況:
1.作為構(gòu)造器生成的實(shí)例對(duì)象
2.作為調(diào)用當(dāng)前方法的對(duì)象
3.在 JS 頂層代碼可以使用 this 代表 window 調(diào)用全局函數(shù)等

故當(dāng)我們使用 call 方法調(diào)用某個(gè)對(duì)象的方法時(shí),雖然從代碼語義上看,這個(gè)所屬方法是屬于該對(duì)象的(showName 屬于 Dog 或 Cat),但是由于函數(shù)有用其特殊的獨(dú)立性即有以上幾個(gè)關(guān)于 this 的特點(diǎn),導(dǎo)致最終的結(jié)果是不同的.
當(dāng)我們直接調(diào)用 dog 的 showName 方法時(shí),showName 方法內(nèi)的 this 指向的是該dog 對(duì)象(Dog 實(shí)例).

我們知道調(diào)用 call 方法時(shí)需要傳入的第一個(gè)參數(shù)即為調(diào)用當(dāng)前函數(shù)亦或方法的對(duì)象,此時(shí)被調(diào)用的方法的 this 指向的實(shí)際為傳入的第一個(gè)參數(shù).即當(dāng)我們通過 call 調(diào)通 dog 的 showName 方法時(shí),傳入的第一個(gè)參數(shù)是 cat 對(duì)象,代表 dog 的 showName 方法的 this 此時(shí)指向的不是 dog 是 cat.最后輸出的當(dāng)然是 cat 的內(nèi)容

最后指出:在對(duì)函數(shù)進(jìn)行傳參時(shí),若傳的是 JS 的基本類型,則為值傳遞,否則為引用傳遞.

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/86053.html

相關(guān)文章

  • 10個(gè)JavaScript難點(diǎn)

    摘要:每個(gè)構(gòu)造函數(shù)都有一個(gè)屬性,用于設(shè)置所有實(shí)例對(duì)象需要共享的屬性和方法。憑直覺,函數(shù)重載可以通過或者實(shí)現(xiàn),這就不去管它了。自從年雙十一正式上線,累計(jì)處理了億錯(cuò)誤事件,得到了金山軟件等眾多知名用戶的認(rèn)可。 譯者按:能夠讀懂這篇博客的JavaScript開發(fā)者,運(yùn)氣不會(huì)太差... 原文: 10 JavaScript concepts every Node.js programmer must ...

    anquan 評(píng)論0 收藏0
  • Backbone.js學(xué)習(xí)筆記(二)細(xì)說MVC

    摘要:因?yàn)槭且粭l數(shù)據(jù)記錄,也就是說,相當(dāng)于是一個(gè)數(shù)據(jù)集。通常我們需要重載函數(shù),聲明,以及通過或?yàn)橐晥D指定根元素。通過綁定視圖的函數(shù)到模型的事件模型數(shù)據(jù)會(huì)即時(shí)的顯示在中。實(shí)例屬性參數(shù)以及類屬性參數(shù)會(huì)被直接注冊(cè)到集合的構(gòu)造函數(shù)。 對(duì)于初學(xué)backbone.js的同學(xué)可以先參考我這篇文章:Backbone.js學(xué)習(xí)筆記(一) Backbone源碼結(jié)構(gòu) showImg(https://segme...

    taoszu 評(píng)論0 收藏0
  • 淺談框架和庫的區(qū)別

    摘要:只是站在初學(xué)者的角度,對(duì)框架和庫的區(qū)別有自己的認(rèn)識(shí)和見解。庫的使用非常靈活,但沒有框架方便,這就是框架和庫本質(zhì)的區(qū)別。框架和庫的區(qū)別庫是將代碼集合成的一個(gè)產(chǎn)品,供程序員調(diào)用。 什么是框架和庫? 初識(shí)框架和庫 對(duì)于好多初學(xué)者來說(例如我),很容易把框架和庫搞混淆,分不清它們的具體區(qū)別,直到現(xiàn)在我也不是把框架和庫搞得很清晰。只是站在初學(xué)者的角度,對(duì)框架和庫的區(qū)別有自己的認(rèn)識(shí)和見解。所以今...

    reclay 評(píng)論0 收藏0
  • js基礎(chǔ)深入淺出

    摘要:當(dāng)多個(gè)事件觸發(fā)的時(shí)候,會(huì)把異步事件依次的放入里等同步事件執(zhí)行完之后,再去隊(duì)列里一個(gè)個(gè)執(zhí)行拾遺常用方法總結(jié)面試的信心來源于過硬的基礎(chǔ)參考高級(jí)程序設(shè)計(jì)你所不知道的深入淺出知識(shí)點(diǎn)思維導(dǎo)圖經(jīng)典實(shí)例總結(jié)那些剪不斷理還亂的關(guān)系 持續(xù)不斷更新。。。 基本類型和引用類型 vue props | Primitive vs Reference Types 基本類型和字面值之間的區(qū)別 基本類型和字面值相等,...

    phodal 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<