js-this/call/apply/bind

this指向

this-運行期綁定,this指向調(diào)用時決定拍顷。

  1. 全局 this指向window
  2. 函數(shù)中抚太,若有調(diào)用者,則this指向調(diào)用者昔案;若為獨立調(diào)用尿贫,則this為undefined。在非嚴格模式中踏揣,當this指向undefined時庆亡,它會被自動指向全局對象。
  3. call/apply/bind 可以改變this指向為第一個參數(shù)
  4. new this指向新構(gòu)造出來的實例對象
  5. 箭頭函數(shù)捞稿,沒有自己的this又谋,會捕獲上下文中的this指向拼缝,即最近的非箭頭函數(shù)中的this指向。
  6. dom事件中彰亥,this指向DOM節(jié)點咧七。

call

function.call(thisArg, arg1, arg2, ...)
thisArg
可選的。在 function 函數(shù)運行時使用的 this 值任斋。請注意继阻,this可能不是該方法看到的實際值:如果這個函數(shù)處于非嚴格模式下,則指定為 nullundefined 時會自動替換為指向全局對象废酷,原始值會被包裝瘟檩。
arg1, arg2, ...
指定的參數(shù)列表。
返回
調(diào)用有指定this值和參數(shù)的函數(shù)的結(jié)果锦积。

芒帕!參數(shù)一個個列表式傳入

Function.prototype.call2 = function (context) {
    // 如果沒傳this指向,則指向window
    var context = context || window;

    // 把要調(diào)用的函數(shù)綁定到對象上, Symbol保證唯一性丰介,不覆蓋已有屬性
    var fn = Symbol();
    context[fn] = this;

    // 處理參數(shù)列表 
    var args = [];
    for(var i = 1, len = arguments.length; i < len; i++) {
        args.push(arguments[i]);
    }
    
    // 執(zhí)行函數(shù)
    var result = context.fn(...args);
    
    // 刪除綁定
    delete context.fn

    // 返回結(jié)果
    return result;
}

Function.prototype.call3 = function(context) {
    return this.apply([].shift.apply(arguments), arguments);
}

apply

func.apply(thisArg, [argsArray])
thisArg
必選的背蟆。在 func 函數(shù)運行時使用的 this 值。請注意哮幢,this可能不是該方法看到的實際值:如果這個函數(shù)處于[非嚴格模式]下带膀,則指定為 nullundefined 時會自動替換為指向全局對象,原始值會被包裝橙垢。
argsArray
可選的垛叨。一個數(shù)組或者類數(shù)組對象,其中的數(shù)組元素將作為單獨的參數(shù)傳給 func 函數(shù)柜某。如果該參數(shù)的值為 [null]嗽元,則表示不需要傳入任何參數(shù)。從ECMAScript 5 開始可以使用類數(shù)組對象喂击。
返回
調(diào)用有指定this值和參數(shù)的函數(shù)的結(jié)果剂癌。

!參數(shù)以數(shù)組形式傳入

Function.prototype.apply2 = function (context翰绊,args) {
    // 如果沒傳this指向佩谷,則指向window
    var context = context || window;

     // 把要調(diào)用的函數(shù)綁定到對象上, Symbol保證唯一性,不覆蓋已有屬性
    var fn = Symbol();
    context[fn] = this;
    
    // 執(zhí)行函數(shù)
    var result = context.fn(...args);
    
    // 刪除綁定
    delete context.fn

    // 返回結(jié)果
    return result;
}

Function.prototype.apply3 = function(context, args) {
    return this.call(context, ...args)
}

bind

Function.prototype.bind2 = function (context) {

    var self = this;
    // 獲取bind2函數(shù)從第二個參數(shù)到最后一個參數(shù)
    var args = Array.prototype.slice.call(arguments, 1);

    return function () {
        // 這個時候的arguments是指bind返回的函數(shù)傳入的參數(shù)
        var bindArgs = Array.prototype.slice.call(arguments);
        return self.apply(context, args.concat(bindArgs));
    }
}

Function.prototype.bind = Function.prototype.bind || function bind(thisArg){
    // 非函數(shù)調(diào)用监嗜,直接報錯
    if(typeof this !== 'function'){
        throw new TypeError(this + ' must be a function');
    }

    var self = this;
    var args = [].slice.call(arguments, 1);
    var bound = function(){
        // 處理參數(shù)合并
        var boundArgs = [].slice.call(arguments);
        var finalArgs = args.concat(boundArgs);
        
        // new 當構(gòu)造函數(shù)使用
        // 用new.target判斷更準確
        if(this instanceof bound){
            if(self.prototype){
                function Empty(){}
                Empty.prototype = self.prototype;
                bound.prototype = new Empty();
            }
            var result = self.apply(this, finalArgs);
            // 構(gòu)造函數(shù)返回值為非對象谐檀、函數(shù),返回構(gòu)造出的實例對象
            var isObject = typeof result === 'object' && result !== null;
            var isFunction = typeof result === 'function';
            if(isObject || isFunction){
                return result;
            }
            return this;
        }
        else{
            return self.apply(thisArg, finalArgs);
        }
    };
    return bound;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末裁奇,一起剝皮案震驚了整個濱河市桐猬,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌刽肠,老刑警劉巖课幕,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件厦坛,死亡現(xiàn)場離奇詭異,居然都是意外死亡乍惊,警方通過查閱死者的電腦和手機杜秸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來润绎,“玉大人撬碟,你說我怎么就攤上這事±蚱玻” “怎么了呢蛤?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長棍郎。 經(jīng)常有香客問我其障,道長,這世上最難降的妖魔是什么涂佃? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任励翼,我火速辦了婚禮,結(jié)果婚禮上辜荠,老公的妹妹穿的比我還像新娘汽抚。我一直安慰自己,他們只是感情好伯病,可當我...
    茶點故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布造烁。 她就那樣靜靜地躺著,像睡著了一般午笛。 火紅的嫁衣襯著肌膚如雪惭蟋。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天药磺,我揣著相機與錄音敞葛,去河邊找鬼。 笑死与涡,一個胖子當著我的面吹牛愉烙,可吹牛的內(nèi)容都是我干的箱叁。 我是一名探鬼主播,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼莺治,長吁一口氣:“原來是場噩夢啊……” “哼鸿秆!你這毒婦竟也來了酌畜?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤卿叽,失蹤者是張志新(化名)和其女友劉穎桥胞,沒想到半個月后恳守,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡贩虾,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年催烘,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片缎罢。...
    茶點故事閱讀 38,789評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡伊群,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出策精,到底是詐尸還是另有隱情舰始,我是刑警寧澤,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布咽袜,位于F島的核電站丸卷,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏询刹。R本人自食惡果不足惜谜嫉,卻給世界環(huán)境...
    茶點故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望范抓。 院中可真熱鬧骄恶,春花似錦、人聲如沸匕垫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽象泵。三九已至寞秃,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間偶惠,已是汗流浹背春寿。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留忽孽,地道東北人绑改。 一個月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像兄一,于是被迫代替她去往敵國和親厘线。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,697評論 2 351

推薦閱讀更多精彩內(nèi)容