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

資訊專欄INFORMATION COLUMN

javascript系列--this指向和apply,call,bind三者的區(qū)別

happen / 2156人閱讀

摘要:一前言指向,,,的區(qū)別是一個(gè)經(jīng)典的面試問題,同時(shí)在項(xiàng)目中會(huì)經(jīng)常使用到的原生的方法。中可能會(huì)極大的避免了產(chǎn)生的錯(cuò)誤,有時(shí)候需要維護(hù)老的項(xiàng)目還是有必要了解一下的指向和,,三者的區(qū)別。

一、前言

this指向,apply,call,bind的區(qū)別是一個(gè)經(jīng)典的面試問題,同時(shí)在項(xiàng)目中會(huì)經(jīng)常使用到的原生的js方法。同時(shí)也是ES5中的眾多坑的一個(gè)。ES6中可能會(huì)極大的避免了this產(chǎn)生的錯(cuò)誤,有時(shí)候需要維護(hù)老的項(xiàng)目還是有必要了解一下this的指向和apply,call,bind三者的區(qū)別。

二、this的指向

在ES5中,其實(shí)this的指向,始終堅(jiān)持一個(gè)原理:this永遠(yuǎn)指向最后一個(gè)調(diào)用它的那個(gè)對象。

首先我們看一個(gè)栗子1:

var name = "windowsName";
function a() {
    var name = "Cherry";
    console.log(this.name);          // windowsName
    console.log("inner:" + this);    // inner: Window
}
a();
console.log("outer:" + this)         // outer: Window

輸出windowsName,是因?yàn)椤皌his永遠(yuǎn)指向最后調(diào)用它的那個(gè)對象”,我們看到調(diào)用a的地方a(),前面沒有調(diào)用的對象那么就是全局對象window,就是全局對象調(diào)用a(),相當(dāng)于window.a()。

如果使用嚴(yán)格模式,全局對象就是undefined,會(huì)報(bào)錯(cuò)name of undefined

栗子2:

var name = "windowsName";
var a = {
    name: "Cherry",
    fn : function () {
        console.log(this.name);      // Cherry
    }
}
a.fn();

在這個(gè)栗子中,函數(shù)fn是對象a調(diào)用的,所以console是a中的name

栗子3:

var name = "windowsName";
    var a = {
        name: "Cherry",
        fn : function () {
            console.log(this.name);      // Cherry
        }
    }
    window.a.fn();

這個(gè)栗子中,記住“this永遠(yuǎn)指向最后一個(gè)調(diào)用它的那個(gè)對象”,調(diào)用fn的對象有window,a,但是最后調(diào)用fn是a對象,所以this指向?qū)ο骯中的name。

栗子4:

var name = "windowsName";
var a = {
    // name: "Cherry",
    fn : function () {
        console.log(this.name);      // undefined
    }
}
window.a.fn();

為啥undefined,調(diào)用fn的對象有:window,a,最后一個(gè)調(diào)用fn是a,但是a中沒有對那么進(jìn)行定義,也不會(huì)繼續(xù)向上一個(gè)對象尋找 this.name,而是直接輸出 undefined,所以this.name為undefined。

栗子5(比較坑):

var name = "windowsName";
var a = {
    name : null,
    // name: "Cherry",
    fn : function () {
        console.log(this.name);      // windowsName
    }
}
var f = a.fn;
f();

這個(gè)栗子比較坑,為啥 不是null,因?yàn)殡m然將a對象的fn方法賦值給變量f,但是沒有調(diào)用,“this永遠(yuǎn)執(zhí)行最后一個(gè)調(diào)用ta的那個(gè)對象”,由于剛剛的f沒有調(diào)用,所以fn()最后仍然是被window調(diào)用的,所以this指向的也就是window。

注意:this的指向并不是在創(chuàng)建的時(shí)候可以確定,在ES5中,永遠(yuǎn)都是this永遠(yuǎn)指向最后調(diào)用它的那個(gè)對象。

栗子6:

var name = "windowsName";
function fn() {
    var name = "Cherry";
    innerFunction();
    function innerFunction() {
        console.log(this.name);      // windowsName
    }
}
fn()
三、怎樣改變this的指向

改變this的指向,我總結(jié)以下的方法:

(1)使用ES6中箭頭函數(shù)

(2)函數(shù)內(nèi)部使用_this = this

(3)使用apply,call,bind方法

(4)new實(shí)例化一個(gè)對象

舉個(gè)栗子7:

var name = "windowsName";
var a = {
    name : "Cherry",
    func1: function () {
        console.log(this.name)     
    },
    func2: function () {
        setTimeout(  function () {
            this.func1()
        },100);
    }
};
a.func2()     // this.func1 is not a function

在這個(gè)栗子中,不使用箭頭函數(shù)情況下,會(huì)報(bào)錯(cuò)的,因?yàn)樽詈笳{(diào)用setTimeout的對象時(shí)window,但是在window并沒有func1函數(shù)。

我們改變this的指向這一節(jié)將吧這個(gè)栗子作為demo進(jìn)行改造。

1、ES6中的箭頭函數(shù)

眾所周知,ES6的箭頭函數(shù)是可以避免ES5中this的坑,箭頭函數(shù)的this始終指向函數(shù)定義時(shí)候的this,而并不是執(zhí)行時(shí)候。箭頭函數(shù)需要記住這句話:“箭頭函數(shù)沒有this綁定,必須通過查找作用域來決定其值,如果箭頭函數(shù)被非箭頭函數(shù)包含,則this的綁定的是最近一層非箭頭函數(shù)的this,否則,this為undefined”

栗子8:

var name = "windowsName";
var a = {
    name : "Cherry",
    func1: function () {
        console.log(this.name)     
    },
    func2: function () {
        setTimeout( () => {
            this.func1()
        },100);
    }
};
a.func2()     // Cherry
2、在函數(shù)內(nèi)部使用_this = this

在不使用ES6中,那么這種方式應(yīng)該是最簡單的不會(huì)出錯(cuò)的方式,我們先將調(diào)用這個(gè)函數(shù)的對象保存在變量_this中,然后在函數(shù)中都使用這個(gè)_this,這樣_this就不會(huì)改變了。

栗子9:

var name = "windowsName";
var a = {
    
    name : "Cherry",
    func1: function () {
        console.log(this.name)     
    },
    func2: function () {
        var _this = this;
        setTimeout( function() {
            _this.func1()
        },100);
    }
};
a.func2()       // Cherry

在func2中,首先設(shè)置var _this = this,這里this是調(diào)用func2的對象a,為了防止在func2中的setTimeout被window調(diào)用而導(dǎo)致的在setTimeout中的this為window。我們將this賦值給一個(gè)變量_this,這樣在func2中我們使用_this就是指向?qū)ο骯了。

3、使用apply

栗子10:

var a = {
    name : "Cherry",
    func1: function () {
        console.log(this.name)
    },
    func2: function () {
        setTimeout(  function () {
            this.func1()
        }.apply(a),100);
    }
};
a.func2()            // Cherry

在栗子中,apply()方法調(diào)用一個(gè)函數(shù),其具有一個(gè)指定的this值,以及作為一個(gè)數(shù)組(或者類似數(shù)組的對象)提供的參數(shù),fun.apply(thisArg, [argsArray])

thisArg:在fun函數(shù)運(yùn)行時(shí)指定的this值。指定this的值并不一定是函數(shù)執(zhí)行時(shí)真正的this值,如果是原始值的this會(huì)指向該原始值的自動(dòng)包裝對象。

argsArray:一個(gè)數(shù)組或者類數(shù)組對象,其中的數(shù)組元素將作為多帶帶的參數(shù)傳給fun函數(shù)。參數(shù)為null或者undefined,則表示不需要傳入任何參數(shù)。

4、使用call

栗子11:

var a = {
    name : "Cherry",
    func1: function () {
        console.log(this.name)
    },
    func2: function () {
        setTimeout(  function () {
            this.func1()
        }.call(a),100);
    }
};
a.func2()            // Cherry

在栗子中,call()方法調(diào)用一個(gè)函數(shù),其具有一個(gè)指定的this值,以及若干個(gè)參數(shù)列表,fun.call(thisArg, arg1, arg2, ...)

thisArg:在fun函數(shù)運(yùn)行時(shí)指定的this值。指定this的值并不一定是函數(shù)執(zhí)行時(shí)真正的this值,如果是原始值的this會(huì)指向該原始值的自動(dòng)包裝對象。

arg1, arg2, ...:若干個(gè)參數(shù)列表

5、使用bind

栗子12:

var a = {
    name : "Cherry",
    func1: function () {
        console.log(this.name)
    },
    func2: function () {
        setTimeout(  function () {
            this.func1()
        }.bind(a)(),100);
    }
};
a.func2()            // Cherry

在栗子中,bind()方法創(chuàng)建一個(gè)新的函數(shù),當(dāng)被調(diào)用時(shí),將其this的關(guān)鍵字設(shè)置為提供的值,在調(diào)用新函數(shù)時(shí),在任何提供一個(gè)給定的參數(shù)序列。

bind創(chuàng)建了一個(gè)新函數(shù),必須手動(dòng)去調(diào)用。

四、apply,call,bind區(qū)別 1、apply和call的區(qū)別

apply和call基本類似,他們的區(qū)別只是傳入的參數(shù)不同。apply傳入的參數(shù)是包含多個(gè)參數(shù)的數(shù)組,call傳入的參數(shù)是若干個(gè)參數(shù)列表。

栗子13:

var a ={
    name : "Cherry",
    fn : function (a,b) {
        console.log( a + b);
        console.log( this.name );
    }
}
var b = a.fn;
b.apply(a,[1,2])     // 3   Cherry

栗子14:

var a ={
    name : "Cherry",
    fn : function (a,b) {
        console.log( a + b);
        console.log( this.name );
    }
}
var b = a.fn;
b.call(a,1,2)       // 3   Cherry
2、bind和apply、call區(qū)別

bind方法會(huì)創(chuàng)建一個(gè)新的函數(shù),當(dāng)被調(diào)用的時(shí)候,將其this關(guān)鍵字設(shè)置為提供的值,我們必須手動(dòng)去調(diào)用。

var a ={
    name : "Cherry",
    fn : function (a,b) {
        console.log( a + b);
        console.log( this.name );
    }
}
var b = a.fn;
b.bind(a,1,2)()   //3   //Cherry

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

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

相關(guān)文章

  • JS系列call & apply & bind

    摘要:參考鏈接在中,和是對象自帶的三個(gè)方法,都是為了改變函數(shù)體內(nèi)部的指向。返回值是函數(shù)方法不會(huì)立即執(zhí)行,而是返回一個(gè)改變了上下文后的函數(shù)。而原函數(shù)中的并沒有被改變,依舊指向全局對象。原因是,在中,多次是無效的。 參考鏈接:https://juejin.im/post/59bfe8... 在JavaScript中,call、apply和bind是Function對象自帶的三個(gè)方法,都是為了改變...

    xiaochao 評論0 收藏0
  • javascript關(guān)于this 以及this顯示設(shè)置(apply、callbind)

    摘要:如果連續(xù)呢結(jié)果會(huì)是什么結(jié)果還是第一個(gè)原因是,在中,多次是無效的。更深層次的原因,的實(shí)現(xiàn),相當(dāng)于使用函數(shù)在內(nèi)部包了一個(gè),第二次相當(dāng)于再包住第一次故第二次以后的是無法生效的。 this 1.其實(shí)js中的this沒那么難理解,當(dāng)找不到this時(shí)記住一句話:誰調(diào)我,我就指誰!new 誰指誰 function text1(){ console.log(this); //指wind...

    LiveVideoStack 評論0 收藏0
  • Javascript-apply、call、bind

    摘要:的作用在中,三者作用是改變某個(gè)函數(shù)的執(zhí)行上下文,具體作用是改變函數(shù)體內(nèi)部的指向。 apply、call、bind的作用 在javascript中,三者作用是改變某個(gè)函數(shù)的執(zhí)行上下文(Execution Context),具體作用是改變函數(shù)體內(nèi)部this的指向。 舉個(gè)栗子: function example() {} example.prototype = { name: wil...

    alexnevsky 評論0 收藏0
  • 理解 JavaScript call()/apply()/bind()

    摘要:理解文章中已經(jīng)比較全面的分析了在中的指向問題,用一句話來總結(jié)就是的指向一定是在執(zhí)行時(shí)決定的,指向被調(diào)用函數(shù)的對象。與和直接執(zhí)行原函數(shù)不同的是,返回的是一個(gè)新函數(shù)。這個(gè)新函數(shù)包裹了原函數(shù),并且綁定了的指向?yàn)閭魅氲摹? 理解 JavaScript this 文章中已經(jīng)比較全面的分析了 this 在 JavaScript 中的指向問題,用一句話來總結(jié)就是:this 的指向一定是在執(zhí)行時(shí)決定的,...

    duan199226 評論0 收藏0
  • JavaScript this 從此不再疑惑

    摘要:是的,始終指向調(diào)用對象,調(diào)用對象,這個(gè)很重要,的靜態(tài)成員是沒有的概念的。所以和,的區(qū)別是返回一個(gè)明確的新函數(shù),和立即執(zhí)行了。 1. 問題引入 function A() {} A.prototype.fna = function() { console.log(this); } 我的問題是 fna 的 this 是指向哪里的? var a = new A(); a.fna(); ...

    Barrior 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<