国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

js函數this理解?手寫apply、call、bind就夠了

Cciradih / 665人閱讀

摘要:一是什么函數的內部屬性,引用的是函數據以執行的環境對象。函數做為節點事件調用時指向節點本身做為構造函數實力化方法時指向實例對象箭頭函數里的普通函數,由于閉包函數是執行的,所以指向箭頭函數的指向函數創建時的作用域。

一、this是什么?

函數的內部屬性,this引用的是函數據以執行的環境對象。也就是說函數的this會指向調用函數的執行環境

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

函數的 this 關鍵字在 JavaScript 中的表現略有不同,此外,在嚴格模式和非嚴格模式之間也會有一些差別。

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

this做為函數的關鍵字,指向函數的調用對象。

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

1.函數做為全局環境調用時
var name = "window";
function a(){
    return  this.name
}
a() ==="window" //true
2.函數做為對象方法調用時
var obj = {
    name:"obj",
    sayName:function(){
        return this.name
    }
}
console.log( obj.sayName() === "obj") //true

//稍微改動一下;添加下面代碼。

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

//此時,sayName函數里的this指向了window。

這里需要明白一點,函數名僅僅是一個包含指針的變量,函數是復雜數據類型,所以函數名就只是一個指針,指向堆中的內存地址!所以sayName此時只是復制了指針地址,所以,上面代碼改寫成下面就很清晰了。

var sayName = function(){
    return this.name
}
var obj = {
    name:"obj",
    sayName:sayName
}
console.log( obj.sayName() === "obj") //true
console.log( sayName() === "obj") //false
3.函數做為dom節點事件調用時
var container3 = document.getElementById("container3")
container3.onclick = function(){ //指向節點本身
    console.log(this) //
container3
}
4.做為構造函數實力化方法時
function A(name){
    this.name = name;
    this.sayName = function(){
        console.log(this.name)//指向實例對象
    }
}
var a = new A("aa");
a.sayName(); //aa
5.箭頭函數里的this
var name = "window"
var obj = {
    name:"obj",
    fn:function(){    
       (function (){
        console.log(this.name)
       })()
    }    

}
obj.fn() //window

普通函數,由于閉包函數是window執行的,所以this指向window;
箭頭函數的this指向函數創建時的作用域。

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

}
obj.fn()

改成箭頭函數,后可以看出創建時的作用域是obj.fn函數執行是的作用域,也就是obj
三、this指向怎么改

js提供了一些可以改變函數執行作用域的方法。因為普通函數如果通過上面的寫法來改變this執行時上下文,寫法就太過于麻煩。

apply、call、bind用法

apply:
fn.apply(thisObj,數組參數)
定義:應用某一個對象的一個方法,用另一個對象替換當前對象
說明:如果參數不是數組類型的,則會報一個TypeError錯誤。

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

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

apply、call、bind實現
apply的實現:

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

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

Function.prototype.myCall= function(context){
    context.fn = this;//1.將函數掛載到傳入的對象
    var arg = [...arguments].splice(1);//2.取參數
    context.fn(...arg) //3.執行對象的方法
    delete context.fn; //4.移除對象的方法
}
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上的實現:

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

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/106553.html

相關文章

  • 「中高級前端面試」JavaScript手寫代碼無敵秘籍

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

    Zhuxy 評論0 收藏0
  • 前端基礎匯總

    摘要:及相關問題數據類型函數中指向原型作用域閉包面向對象對象創建模式繼承嚴格模式與對象轉換的方法添加屬性,根據原型創建區別新特性解構賦值簡化對象寫法剪頭函數三點運算符模板字符串形參默認值異步過程深拷貝與淺拷貝賦值與淺拷貝的區別淺拷貝的幾種方法實現 js及es相關問題 數據類型函數中this指向——————原型作用域閉包——————面向對象對象創建模式繼承——————Es5嚴格模式Json與j...

    2json 評論0 收藏0
  • 前端基礎匯總

    摘要:及相關問題數據類型函數中指向原型作用域閉包面向對象對象創建模式繼承嚴格模式與對象轉換的方法添加屬性,根據原型創建區別新特性解構賦值簡化對象寫法剪頭函數三點運算符模板字符串形參默認值異步過程深拷貝與淺拷貝賦值與淺拷貝的區別淺拷貝的幾種方法實現 js及es相關問題 數據類型函數中this指向——————原型作用域閉包——————面向對象對象創建模式繼承——————Es5嚴格模式Json與j...

    laznrbfe 評論0 收藏0
  • javascript 基礎之 call, apply, bind

    摘要:系統,扎實的語言基礎是一個優秀的前端工程師必須具備的。第一個參數為調用函數時的指向,隨后的參數則作為函數的參數并調用,也就是。和的區別只有一個,就是它只有兩個參數,而且第二個參數為調用函數時的參數構成的數組。 系統,扎實的 javascript 語言基礎是一個優秀的前端工程師必須具備的。在看了一些關于 call,apply,bind 的文章后,我還是打算寫下這篇總結,原因其實有好幾個。...

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

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

    wuaiqiu 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<