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

資訊專欄INFORMATION COLUMN

js函數(shù)this理解?手寫(xiě)apply、call、bind就夠了

Cciradih / 689人閱讀

摘要:一是什么函數(shù)的內(nèi)部屬性,引用的是函數(shù)據(jù)以執(zhí)行的環(huán)境對(duì)象。函數(shù)做為節(jié)點(diǎn)事件調(diào)用時(shí)指向節(jié)點(diǎn)本身做為構(gòu)造函數(shù)實(shí)力化方法時(shí)指向?qū)嵗龑?duì)象箭頭函數(shù)里的普通函數(shù),由于閉包函數(shù)是執(zhí)行的,所以指向箭頭函數(shù)的指向函數(shù)創(chuàng)建時(shí)的作用域。

一、this是什么?

函數(shù)的內(nèi)部屬性,this引用的是函數(shù)據(jù)以執(zhí)行的環(huán)境對(duì)象。也就是說(shuō)函數(shù)的this會(huì)指向調(diào)用函數(shù)的執(zhí)行環(huán)境。

function a(){
    return  this
}
console.log( a() === window) //true

函數(shù)的 this 關(guān)鍵字在 JavaScript 中的表現(xiàn)略有不同,此外,在嚴(yán)格模式和非嚴(yán)格模式之間也會(huì)有一些差別。

function a(){
    "use strict"
    return  this
}
console.log( a() === undefined) //true
二、this指向哪里

this做為函數(shù)的關(guān)鍵字,指向函數(shù)的調(diào)用對(duì)象。

大致的指向總結(jié)歸納為可以分為以下幾種:

1.函數(shù)做為全局環(huán)境調(diào)用時(shí)
var name = "window";
function a(){
    return  this.name
}
a() ==="window" //true
2.函數(shù)做為對(duì)象方法調(diào)用時(shí)
var obj = {
    name:"obj",
    sayName:function(){
        return this.name
    }
}
console.log( obj.sayName() === "obj") //true

//稍微改動(dòng)一下;添加下面代碼。

var sayName = obj.sayName;
console.log( sayName() === "obj") //false

//此時(shí),sayName函數(shù)里的this指向了window。

這里需要明白一點(diǎn),函數(shù)名僅僅是一個(gè)包含指針的變量,函數(shù)是復(fù)雜數(shù)據(jù)類(lèi)型,所以函數(shù)名就只是一個(gè)指針,指向堆中的內(nèi)存地址!所以sayName此時(shí)只是復(fù)制了指針地址,所以,上面代碼改寫(xiě)成下面就很清晰了。

var sayName = function(){
    return this.name
}
var obj = {
    name:"obj",
    sayName:sayName
}
console.log( obj.sayName() === "obj") //true
console.log( sayName() === "obj") //false
3.函數(shù)做為dom節(jié)點(diǎn)事件調(diào)用時(shí)
var container3 = document.getElementById("container3")
container3.onclick = function(){ //指向節(jié)點(diǎn)本身
    console.log(this) //
container3
}
4.做為構(gòu)造函數(shù)實(shí)力化方法時(shí)
function A(name){
    this.name = name;
    this.sayName = function(){
        console.log(this.name)//指向?qū)嵗龑?duì)象
    }
}
var a = new A("aa");
a.sayName(); //aa
5.箭頭函數(shù)里的this
var name = "window"
var obj = {
    name:"obj",
    fn:function(){    
       (function (){
        console.log(this.name)
       })()
    }    

}
obj.fn() //window

普通函數(shù),由于閉包函數(shù)是window執(zhí)行的,所以this指向window;
箭頭函數(shù)的this指向函數(shù)創(chuàng)建時(shí)的作用域。

var name = "window"
var obj = {
    name:"obj",
    fn:function(){    
       (()=>{ //改成箭頭函數(shù)
        console.log(this.name)
       })()
    }    

}
obj.fn()

改成箭頭函數(shù),后可以看出創(chuàng)建時(shí)的作用域是obj.fn函數(shù)執(zhí)行是的作用域,也就是obj
三、this指向怎么改

js提供了一些可以改變函數(shù)執(zhí)行作用域的方法。因?yàn)槠胀ê瘮?shù)如果通過(guò)上面的寫(xiě)法來(lái)改變this執(zhí)行時(shí)上下文,寫(xiě)法就太過(guò)于麻煩。

apply、call、bind用法

apply:
fn.apply(thisObj,數(shù)組參數(shù))
定義:應(yīng)用某一個(gè)對(duì)象的一個(gè)方法,用另一個(gè)對(duì)象替換當(dāng)前對(duì)象
說(shuō)明:如果參數(shù)不是數(shù)組類(lèi)型的,則會(huì)報(bào)一個(gè)TypeError錯(cuò)誤。

call:
fn.call(thisObj, arg1, arg2, argN)
apply與call的唯一區(qū)別就是接收參數(shù)的格式不同。

bind:
fn.bind(thisObj, arg1, arg2, argN)
bind()方法創(chuàng)建一個(gè)新的函數(shù),在bind()被調(diào)用時(shí),這個(gè)新函數(shù)的this被bind的第一個(gè)參數(shù)指定,其余的參數(shù)將作為新函數(shù)的參數(shù)供調(diào)用時(shí)使用。

apply、call、bind實(shí)現(xiàn)
apply的實(shí)現(xiàn):

Function.prototype.myApply= function(context){
    context.fn = this;//1.將函數(shù)掛載到傳入的對(duì)象
    var arg = [...arguments].splice(1)[0];//2.取參數(shù)
    if(!Array.isArray(arg)) {
        throw new Error("apply的第二個(gè)參數(shù)必須是數(shù)組") //3.限制參數(shù)類(lèi)型為數(shù)組
    }    
    context.fn(arg) //4.執(zhí)行對(duì)象的方法
    delete context.fn; //5.移除對(duì)象的方法
}

var obj = {
    name:"obj"
}
function sayName(arr){
    console.log(this.name,arr)
}
sayName.myApply(obj,[1,2,3]) //obj [1, 2, 3]
call實(shí)現(xiàn):與apply的唯一區(qū)別就是參數(shù)格式不同

Function.prototype.myCall= function(context){
    context.fn = this;//1.將函數(shù)掛載到傳入的對(duì)象
    var arg = [...arguments].splice(1);//2.取參數(shù)
    context.fn(...arg) //3.執(zhí)行對(duì)象的方法
    delete context.fn; //4.移除對(duì)象的方法
}
var obj = {
    name:"obj1"
}
function sayName(){
    console.log(this.name,...arguments)
}
sayName.myCall(obj,1,2,3,5) //obj1 1,2,3,5


bind在mdn上的實(shí)現(xiàn):

Function.prototype.myBind = function(oThis){
    if(typeof this !== "function"){
        throw new TypeError("被綁定的對(duì)象需要是函數(shù)")
    }
    var self = this
    var args = [].slice.call(arguments, 1)
    fBound = function(){ //this instanceof fBound === true時(shí),說(shuō)明返回的fBound被當(dāng)做new的構(gòu)造函數(shù)調(diào)用
        return self.apply(this instanceof fBound ? this : oThis, args.concat([].slice.call(arguments)))
    }
    var func = function(){}
    //維護(hù)原型關(guān)系
    if(this.prototype){
        func.prototype = this.prototype
    }
    //使fBound.prototype是func的實(shí)例,返回的fBound若作為new的構(gòu)造函數(shù),新對(duì)象的__proto__就是func的實(shí)例
    fBound.prototype = new func()
    return fBound
}

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

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

相關(guān)文章

  • 「中高級(jí)前端面試」JavaScript手寫(xiě)代碼無(wú)敵秘籍

    摘要:第一種直接調(diào)用避免在不必要的情況下使用,是一個(gè)危險(xiǎn)的函數(shù),他執(zhí)行的代碼擁有著執(zhí)行者的權(quán)利。來(lái)自于此外,實(shí)現(xiàn)需要考慮實(shí)例化后對(duì)原型鏈的影響。函數(shù)柯里化的主要作用和特點(diǎn)就是參數(shù)復(fù)用提前返回和延遲執(zhí)行。手寫(xiě)路徑導(dǎo)航 實(shí)現(xiàn)一個(gè)new操作符 實(shí)現(xiàn)一個(gè)JSON.stringify 實(shí)現(xiàn)一個(gè)JSON.parse 實(shí)現(xiàn)一個(gè)call或 apply 實(shí)現(xiàn)一個(gè)Function.bind 實(shí)現(xiàn)一個(gè)繼承 實(shí)現(xiàn)一個(gè)J...

    Zhuxy 評(píng)論0 收藏0
  • 前端基礎(chǔ)匯總

    摘要:及相關(guān)問(wèn)題數(shù)據(jù)類(lèi)型函數(shù)中指向原型作用域閉包面向?qū)ο髮?duì)象創(chuàng)建模式繼承嚴(yán)格模式與對(duì)象轉(zhuǎn)換的方法添加屬性,根據(jù)原型創(chuàng)建區(qū)別新特性解構(gòu)賦值簡(jiǎn)化對(duì)象寫(xiě)法剪頭函數(shù)三點(diǎn)運(yùn)算符模板字符串形參默認(rèn)值異步過(guò)程深拷貝與淺拷貝賦值與淺拷貝的區(qū)別淺拷貝的幾種方法實(shí)現(xiàn) js及es相關(guān)問(wèn)題 數(shù)據(jù)類(lèi)型函數(shù)中this指向——————原型作用域閉包——————面向?qū)ο髮?duì)象創(chuàng)建模式繼承——————Es5嚴(yán)格模式Json與j...

    2json 評(píng)論0 收藏0
  • 前端基礎(chǔ)匯總

    摘要:及相關(guān)問(wèn)題數(shù)據(jù)類(lèi)型函數(shù)中指向原型作用域閉包面向?qū)ο髮?duì)象創(chuàng)建模式繼承嚴(yán)格模式與對(duì)象轉(zhuǎn)換的方法添加屬性,根據(jù)原型創(chuàng)建區(qū)別新特性解構(gòu)賦值簡(jiǎn)化對(duì)象寫(xiě)法剪頭函數(shù)三點(diǎn)運(yùn)算符模板字符串形參默認(rèn)值異步過(guò)程深拷貝與淺拷貝賦值與淺拷貝的區(qū)別淺拷貝的幾種方法實(shí)現(xiàn) js及es相關(guān)問(wèn)題 數(shù)據(jù)類(lèi)型函數(shù)中this指向——————原型作用域閉包——————面向?qū)ο髮?duì)象創(chuàng)建模式繼承——————Es5嚴(yán)格模式Json與j...

    laznrbfe 評(píng)論0 收藏0
  • javascript 基礎(chǔ)之 call, apply, bind

    摘要:系統(tǒng),扎實(shí)的語(yǔ)言基礎(chǔ)是一個(gè)優(yōu)秀的前端工程師必須具備的。第一個(gè)參數(shù)為調(diào)用函數(shù)時(shí)的指向,隨后的參數(shù)則作為函數(shù)的參數(shù)并調(diào)用,也就是。和的區(qū)別只有一個(gè),就是它只有兩個(gè)參數(shù),而且第二個(gè)參數(shù)為調(diào)用函數(shù)時(shí)的參數(shù)構(gòu)成的數(shù)組。 系統(tǒng),扎實(shí)的 javascript 語(yǔ)言基礎(chǔ)是一個(gè)優(yōu)秀的前端工程師必須具備的。在看了一些關(guān)于 call,apply,bind 的文章后,我還是打算寫(xiě)下這篇總結(jié),原因其實(shí)有好幾個(gè)。...

    xeblog 評(píng)論0 收藏0
  • js 面試官想了解你有多理解call,apply,bind?

    摘要:返回值這段在下方應(yīng)用中有詳細(xì)的示例解析。回調(diào)函數(shù)丟失的解決方案綁定回調(diào)函數(shù)的指向這是典型的應(yīng)用場(chǎng)景綁定指向,用做回調(diào)函數(shù)。 showImg(https://segmentfault.com/img/remote/1460000019971331?w=1024&h=680); 函數(shù)原型鏈中的 apply,call 和 bind 方法是 JavaScript 中相當(dāng)重要的概念,與 this...

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

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

0條評(píng)論

閱讀需要支付1元查看
<