摘要:的指向除去不常用的和,的指向大致可分為以下四種作為對象的方法調(diào)用作為普通函數(shù)調(diào)用構(gòu)造器調(diào)用或調(diào)用作為對象的方法調(diào)用當(dāng)函數(shù)作為對象的方法被調(diào)用時,指向該對象。
this
和其他語言不同,JavaScript的this總是指向一個對象,而具體指向哪個對象是在運行時基于函數(shù)的執(zhí)行環(huán)境動態(tài)綁定的,而非函數(shù)被聲明時的環(huán)境。
this的指向除去不常用的with和eval,this的指向大致可分為以下四種:
作為對象的方法調(diào)用
作為普通函數(shù)調(diào)用
構(gòu)造器調(diào)用
Function.prototype.call或Function.prototype.apply調(diào)用
作為對象的方法調(diào)用當(dāng)函數(shù)作為對象的方法被調(diào)用時,this指向該對象。
var obj={ a:1, getA:function(){ alert(this===obj);//true alert(this.a);//1 } }; obj.getA();作為普通函數(shù)調(diào)用
當(dāng)函數(shù)不作為對象的屬性被調(diào)用時,也就是普通函數(shù)方式,此時this總是指向全局對象。在瀏覽器中,這個全局對象是window。
window.name="globalName"; var getName1=function(){ return this.name; }; var myObject={ name:"sven", getName:function(){ return this.name; } }; var getName=myObject.getName; alert(getName1());//globalName alert(getName());//globalName構(gòu)造器調(diào)用
當(dāng)用new運算符調(diào)用函數(shù)時,該函數(shù)總會返回一個對象,通常情況下,構(gòu)造器里的this就指向返回的這個對象。
var MyClass=function(){ this.name="sven"; }; var obj=new MyClass(); alert(obj.name);//sven
但是如果構(gòu)造器顯式地返回了一個object類型的對象,那么此次運算結(jié)果最終會返回這個對象,而不是我們之前期待的this:
var MyClass=function(){ this.name="sven"; return{ name:"anne"; } }; var obj=new MyClass(); alert(obj.name);//anne
如果構(gòu)造器不顯式地返回任何數(shù)據(jù),或者是返回一個非對象類型的數(shù)據(jù),就不會造成上述問題:
var MyClass=function(){ this.name="sven"; return "anne"; }; var obj=new MyClass(); alert(obj.name);//svencall和apply調(diào)用
call和apply可以動態(tài)的地改變傳入函數(shù)的this:
var obj1={ name:"sven", getName:function(){ return this.name; } }; var obj2={ name:"anne" }; console.log(obj1.getName()); console.log(obj1.getName.call(obj2));call和apply
call和apply作用一模一樣,區(qū)別在于傳入?yún)?shù)的形式不同。apply接受兩個參數(shù),第一個參數(shù)指定了函數(shù)體內(nèi)this對象的指向,第二個參數(shù)第二個參數(shù)為一個帶下標(biāo)的集合,這個集合可以為數(shù)組,也可以為類數(shù)組。
JavaScript的參數(shù)在內(nèi)部就是用一個數(shù)組來表示的,從這個意義上來說,apply比call的使用率更高。call是包裝在apply上的一顆語法糖,如果我們明確知道函數(shù)接受多少個參數(shù),而且想一目了然地表達(dá)形參和實參的對應(yīng)關(guān)系,那么也可以用call來傳送參數(shù)。
當(dāng)使用call或者apply時,如果我們傳入的第一個參數(shù)是null,函數(shù)體內(nèi)的this會指向默認(rèn)的宿主對象,在瀏覽器中就是window,但如果是在嚴(yán)格模式下,函數(shù)體內(nèi)的this還是為null。
有時候我們使用call或者apply的目的并不在于指定this的指向,而是另有用途,比如借用其他對象的方法,那么我們就可以傳入null來代替某個具體的對象。
call和apply的用途 改變this的指向 Function.prototype.bindFunction.prototype.bind=function() { var self=this, context=[].shift.call(arguments),//需要綁定的this上下文 args=[].slice.call(arguments);//剩余的參數(shù)轉(zhuǎn)成數(shù)組 return function(){ return self.apply(context,[].concat.call(args,[].slice.call(arguments)));//執(zhí)行新的函數(shù)體的時候,會把之前傳入的context當(dāng)作新函數(shù)體內(nèi)的this,并且組合兩次分別傳入的參數(shù),作為新函數(shù)的參數(shù) } }; var obj={ name:"sven" }; var func=function(a,b,c,d){ alert(this.name); alert([a,b,c,d]); }.bind(obj,1,2); func(3,4);使用其他對象的方法
第一種場景是借用構(gòu)造函數(shù),可以實現(xiàn)一些類似繼承的效果:
var A=function(name){ this.name=name; }; var B=function(){ A.apply(this,arguments); }; B.prototype.getName=function(){ return this.name; }; var b=new B("sven"); console.log(b.getName());
第二種場景:函數(shù)的參數(shù)列表arguments是一個類數(shù)組對象,雖然它也有下標(biāo),但她并非真正的數(shù)組,所以不能進行排序操作或者往集合里添加一個新的元素。這種情況下我們常常會借用Array.prototype對象上的方法。比如想往arguments里插入一個元素,通常會借用Array.prototype.push:
(function(){Array.prototype.push.call(arguments,3)})(1,2);
在操作arguments時,我們經(jīng)常非常頻繁地找Array.prototype借用方法。
轉(zhuǎn)化為數(shù)組:Array.prototype.slice
截去頭元素:Array.prototype.shift
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/86282.html
摘要:參數(shù)和是放在數(shù)組中傳入函數(shù),分別對應(yīng)參數(shù)的列表元素。而原函數(shù)中的并沒有被改變,依舊指向全局對象。保存原函數(shù)保存需要綁定的上下文剩余的參數(shù)轉(zhuǎn)為數(shù)組返回一個新函數(shù)下一篇介紹閉包中閉包的詳解。 apply 和 call 的區(qū)別 ECMAScript 規(guī)范給所有函數(shù)都定義了 call 與 apply 兩個方法,它們的應(yīng)用非常廣泛,它們的作用也是一模一樣,只是傳參的形式有區(qū)別而已。 apply(...
摘要:第二行將函數(shù)的指向一個字符串第三行將函數(shù)的指向一個數(shù)字以此類推。再舉一個例子實現(xiàn)對象繼承繼承了的屬性和方法陳安東男姓名年齡性別輸出姓名陳安東年齡性別男這樣用就實現(xiàn)了繼承用也類似 這里排版不是太好,詳情看我的簡書 經(jīng)過網(wǎng)上的大量搜索,漸漸明白了apply()和call方法的使用,為此寫一篇文章記錄一下。 定義 apply()方法: Function.apply(obj,args)obj:...
摘要:也就是說當(dāng)使用后,當(dāng)前執(zhí)行上下文中的對象已被替換為,后續(xù)執(zhí)行將以所持有的狀態(tài)屬性繼續(xù)執(zhí)行。借用的方法替換的實例去調(diào)用相應(yīng)的方法。實現(xiàn)引用類型的繼承其實沒有類這一概念,我們平時使用的等嚴(yán)格來說被稱作引用類型。 call 方法:object.method.call(targetObj[, argv1, argv2, .....]) apply 方法:object.method.apply(...
摘要:當(dāng)沒有使用而直接調(diào)用時指向?qū)ο蠛瘮?shù)和函數(shù)非常的相似,第一個參數(shù)都用來設(shè)置目標(biāo)函數(shù)運行時的指向。輸出的結(jié)果為結(jié)果證明兩個地方傳入的參數(shù)都會被傳給目標(biāo)函數(shù),函數(shù)拷貝調(diào)用時傳入的參數(shù)會追加在函數(shù)調(diào)用時傳入的參數(shù)后面。 call() , apply() 與 bind() 詳解 我們知道可以用call(), apply() 和 bind()這三個函數(shù)都是用來完成函數(shù)調(diào)用,并且設(shè)置this指向。 ...
閱讀 2609·2021-11-17 17:00
閱讀 1864·2021-10-11 10:57
閱讀 3716·2021-09-09 11:33
閱讀 911·2021-09-09 09:33
閱讀 3550·2019-08-30 14:20
閱讀 3312·2019-08-29 11:25
閱讀 2796·2019-08-26 13:48
閱讀 734·2019-08-26 11:52