js call 以及apply

來源:互聯網
上載者:User

標籤:

用執行個體來講;一半什麼場合用到bind、call、apply呢?
【一個對象 A】的方法被【另一個對象 B】【引用】的時候(請注意 引用 的意思,區分 調用 );【對象A】的方法內的this範圍就不指向【對象A】了,這個時候你再用this.XX項調用【對象A】的某個屬性就會發生錯誤。

舉個例子吧;
var aHello = {    name : "hello",    showName : function(){        console.log(this.name);        //console.log(this.tagName);    }}document.querySelector(‘a‘).onclick = aHello.showName;

這個時候因為【對象aHello】的方法showName被【對象document.querySelector(‘a‘)】 引用,所以showName內的this就不指向【aHello】了,指向【對象document.querySelector(‘a‘)】,可以去掉注釋進行驗證。

但是我們的需求是,點擊a的時候就顯示aHello的名稱。

這個時候該怎麼做呢?

方法一:在onclick的時候改用匿名函數,匿名函數內再 調用 【對象aHello】的方法;
如:
var aHello = {    name : "hello",    showName : function(){        console.log(this.name);    }}document.querySelector(‘a‘).onclick = function(){    aHello.showName();}
ok!開心的解決了;

然而,是不是覺得太慫了。我們來衍生一下第二種方法,然後再說bind和call和apply的區別;

方法二:因為 引用, onclick改變了【對象aHello】showName內this的指向。所以我們必須在【 引用】的時候對showName方法進行重新綁定新的指向;
如:

var aHello = {    name : "hello",    showName : function(){        console.log(this.name);    }}document.querySelector(‘a‘).onclick = aHello.showName.bind(aHello);

恩!高大上,不用寫太多代碼。

接下來講一下bind和apply、call的區別;
首先這些方法多屬於【原型prototype】的方法。

題主的老師 可能沒聽過【引用】與【調用】所以用了一個臨時與永久的概念來講解,做技術,最好不要聽老師的......



還用前面例子來講(隨便舉的主要區分區別,大家別挑刺);
var aHello = {    name : "hello",    setYourAge : function(name,age){       console.log(name);       console.log(age);    }}document.querySelector(‘a‘).onclick = aHello.setYourAge.call(aHello,‘王佳欣‘,25);

這個時候你可以看到開啟頁面,瀏覽器控制台就會馬上輸出 “王佳欣”,“25”;
然後,你再點擊的時候,根本不會,再輸出的;ok,這就是 【調用】含義;
call和apply是調用對象方法的意思;也就是說下面的3句代碼其實實現是一樣的;
aHello.setYourAge.call(aHello,‘王佳欣‘,25);aHello.setYourAge.apply(aHello,[‘王佳欣‘,25]);aHello.setYourAge(‘王佳欣‘,25);
既然可以直接調用幹嘛還要call、apply方法呢,我先說一下 call、apply 和bind的區別吧;

var aHello = {    name : "hello",    setYourAge : function(name,age){       console.log(name);       console.log(age);    }}document.querySelector(‘a‘).onclick = aHello.setYourAge.bind(aHello,‘王佳欣‘,25);
bind的作用是【引用】,這個時候你開啟瀏覽器控制台不會有輸出。你點擊a 標籤的後,才會有輸出,點一次,輸出一次。
粗暴一點說,這就是區別馬上【調用】和【引用】的區別。

上面我們說到,下面三局代碼實現是一樣的。那麼call、apply有什麼作用呢?
aHello.setYourAge.call(aHello,‘王佳欣‘,25);aHello.setYourAge.apply(aHello,[‘王佳欣‘,25]);aHello.setYourAge(‘王佳欣‘,25);

call、apply有什麼作用
大家開發中是不是有這樣的需求(我總是喜歡用需求來作為入口)
我們經常會在我們項目中做一些通用的對象,這些對象用來處理我們的一些通用的過程。比如:通用驗證方法;(註:很多人喜歡用 繼承的基礎類 來作為例子.....我一時想不到好的繼承例子,就用通用類的例子吧!)

/*通用驗證對象*/var validator = {    validateName : function(){         console.log(this.name);    },    validateAge  : function(){         console.log(this.age)    }    //.....}

大家可以看到我們的 【通用對象validator】內,是沒有定義屬性(name、age)的。

這個時候比如我們有兩個對象需要驗證;

/*對象kobe*/var kobe = {    name : ‘kobe bryant‘,    age  : -1}/*對象 allen*/ var allen = {    name : ‘allen iverson‘,    age  : 10}


那我們調用驗證的時候就需要用到call或者apply了
如:
var isKobeAgeValid = validator.call(kobe);var isAllenAgeValid = validator.call(allen);

額!差不多了了..... 轉載自 王佳欣
連結:http://www.zhihu.com/question/20289071/answer/93261557
來源:知乎
著作權歸作者所有,轉載請聯絡作者獲得授權。

js call 以及apply

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.