“this” 關(guān)鍵字允許在調(diào)用函數(shù)或方法時(shí)決定哪個(gè)對(duì)象應(yīng)該是焦點(diǎn)。 在JavaScript中this可以是全局對(duì)象、當(dāng)前對(duì)象或者任意對(duì)象,這完全取決于函數(shù)的調(diào)用方式,this 綁定的對(duì)象即函數(shù)執(zhí)行的上下文環(huán)境,在 ES5 中,其實(shí) this 的指向,始終堅(jiān)持一個(gè)原理:this 永遠(yuǎn)指向最后調(diào)用它的那個(gè)對(duì)象,正是由于調(diào)用 關(guān)于this的指向及綁定,請(qǐng)關(guān)注博文 JS五種綁定徹底弄懂this,默認(rèn)綁定、隱式綁定、顯式綁定、new綁定、箭頭函數(shù)綁定詳解 // e.g.1var test = { a: 5, b: 6, sum: function (a, b) { function getA(a) { this.a = a; // 在window上增加了一個(gè)全局變量a return this.a; // 此處this = window } function getB(b) { this.b = b; //在window上增加了一個(gè)全局變量b return this.b; // 此處this = window } return getA(a) + getB(b); } }console.log(test.sum(4, 3)); // 7console.log(a); // 4 (打印結(jié)果為 window.a) console.log(b); // 3 (打印結(jié)果為 window.b) // e.g.2var user = { name: 'Echoyya', age: 27, greet() { console.log(this.name) }, bf: { name: 'KK.unlock', greet() { console.log(this.name) } } } user.greet() // Echoyyauser.bf.greet() // KK.unlock 如果 function greet () { console.log(this.name) }var user = { name: 'Echoyya' } 如何能讓 怎樣改變 this 的指向(1)使用ES6中箭頭函數(shù)箭頭函數(shù)中的 this 始終指向函數(shù)定義時(shí)的 this,而非執(zhí)行時(shí)。箭頭函數(shù)中沒有 this 綁定,必須通過查找作用域鏈來決定其值,如果箭頭函數(shù)被非箭頭函數(shù)包含,則 this 綁定的是最近一層非箭頭函數(shù)的 this,否則,this 為 undefined”。 也正因如此,箭頭函數(shù)不能用于構(gòu)造函數(shù) var name = "windowsName";var obj = { name: "Echoyya", func1: function () { console.log(this.name) }, func2: () => { console.log(this.name) } }; obj.func1() // Echoyyaobj.func2() // windowsName (2)函數(shù)內(nèi)部使用 _this = this如果不使用 ES6,那么這種方式應(yīng)該是最簡(jiǎn)單且不易出錯(cuò)的方式了,先將調(diào)用這個(gè)函數(shù)的對(duì)象保存在變量
var name = "windowsName";var obj = { name: "Echoyya", func: function () { var _this = this; setTimeout(function () { console.log(_this.name) }, 1000); } }; obj.func() // Echoyya (3)使用call,apply,bind方法
call 與 apply
站在函數(shù)應(yīng)用的角度我們知道了call與apply的用途,那這兩個(gè)方法又有什么區(qū)別呢,其實(shí)區(qū)別就一點(diǎn),參數(shù)傳遞方式不同。
除此之外,兩個(gè)方法的效果完全相同: var o = { a: 1};function fn(b, c) { console.log(this.a + b + c); }; fn.call(o, 2, 3); // 6fn.apply(o, [2, 3]); //6 關(guān)于 bindbind要單獨(dú)說一下,因?yàn)樗ccall,apply還不太一樣。call與apply在改變this的同時(shí),就立刻執(zhí)行,而bind綁定this后并不會(huì)立馬執(zhí)行,而是返回一個(gè)新的綁定函數(shù),需要在執(zhí)行一下。 var o = { a: 1};function fn(b, c) { console.log(this.a + b + c); };var fn2 = fn.bind(o, 2, 3); fn2(); //6 var name = 'windowsName'function greet () { console.log(this.name) }var user = { name: 'Echoyya' }greet() // windowsNamegreet.bind()() // windowsName (非嚴(yán)格模式下,默認(rèn)指向window)greet.bind(user)() // Echoyya var obj = { name: "Echoyya", func: function () { setTimeout(function () { console.log(this.name) }.bind(obj)(), 100); } }; obj.func() // Echoyya call、apply、bind 區(qū)別call、apply、bind 都是可以改變 this 的指向的,但是這三個(gè)函數(shù)稍有不同。 var test = { a: 5, b: 6, sum: function (a, b) { var self = this; function getA() { return self.a; } function getB() { return self.b; } console.log(a, b); // call, apply, bind 傳入?yún)?shù) return getA() + getB(); } }var obj = { a: 2, b: 3};console.log(test.sum.call(obj, 4, 5)); // 4,5,5 (self = this = obj) console.log(test.sum.apply(obj, [6, 7])); // 6,7,5 (self = this = obj) console.log(test.sum.bind(obj, 8, 9)()); // 8,9,5 (self = this = obj)
其實(shí)很好理解,當(dāng)執(zhí)行fn1時(shí),本質(zhì)上等于window.fn1(),如果this還能被改變,那this豈不是得指向window,那bind方法就沒太大意義了 |
|