日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關咨詢
選擇下列產(chǎn)品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Knowthis,usethis!(總結(jié)this的常見用法)

this應該是一個討論了很久的話題了。其中,關于this的文章,在很多的博客當中也有很多介紹,但是,以前我都是一知半解的去了解它,就是看博客當中,只介紹了一些情況下的 this 的使用方式,但是也并沒有自己去做過總結(jié)。剛好是在掘金當中有看到一篇關于this的一些詳細文章,文末會附上鏈接以及英文原文,這里純粹是自己進行一個總結(jié),以后方便自己進行回顧以及加深印象。希望這篇文章對于你了解this有一定的幫助,文末還有一些練習題噢~希望真的對你們有幫助。(因為寫項目過程中,一直被 this 坑過,卻找了很久的 bug ,我真是 樂了狗)

為市南等地區(qū)用戶提供了全套網(wǎng)頁設計制作服務,及市南網(wǎng)站建設行業(yè)解決方案。主營業(yè)務為網(wǎng)站制作、做網(wǎng)站、市南網(wǎng)站設計,以傳統(tǒng)方式定制建設網(wǎng)站,并提供域名空間備案等一條龍服務,秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務。我們深信只要達到每一位用戶的要求,就會得到認可,從而選擇與我們長期合作。這樣,我們也可以走得更遠!

在了解this之前,相信大家都應該會知道作用域這個知識點的存在,函數(shù)在創(chuàng)建之后,會構(gòu)建自己的執(zhí)行環(huán)境以及作用域,這是一開始就確定了。但是實際的上下文(context)環(huán)境,也可以理解為就是this,它是動態(tài)確定的,即在函數(shù)運行時才確定this所指向的對象,而非聲明時所指向的對象。

關于this,總結(jié)起來,主要有以下幾個途徑能夠被運用到。

1 對象方法中調(diào)用this

如果函數(shù)被當中對象的一個方法進行調(diào)用,則this值指向該對象。

 
 
  1. var person = {
  2.     name: 'Alice',
  3.     sayName: function() {
  4.         alert('welcome ' + this.name);
  5.     }
  6. }
  7. person.sayName();    // this == person, alert: 'welcome Alice'

 在這里,函數(shù)的this指向該對象(即 person);但是有一點需要注意,就是當對象的方法被賦予給一個變量時,其則變?yōu)榱撕瘮?shù)觸發(fā),此時的this為 window 或者 undefined(嚴格模式下),如下:

 
 
  1. var name = 'Bob';
  2. var person;    // 即上面的定義,此不拓展詳細,直接使用
  3. var say = person.sayName;    // this == window || undefined
  4. say();    // 'welcome Bob' || throw an error: Cannot read property 'name' of undefined(...)

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

在函數(shù)內(nèi)部當中使用了 this,即函數(shù)被當做方法使用,不同于 1 當中作為對象的方法使用,此時調(diào)用,是在全局作用域下進行調(diào)用,即在window下進行調(diào)用,由定義可以知道,在全局作用域下聲明一個函數(shù),其自動加為window的一個屬性。this此時名正言順的會指向window,嚴格模式下為 undefined

 
 
  1. function sayThis() {
  2.     alert(this == window);    // true
  3. }

 結(jié)合第一點,函數(shù)作為對象的一個方法使用,這里存在一個小坑,即閉包,啥是閉包,這個在這里就不扯開了,最簡單的理解就是Function that returns function,如果不理解什么是閉包的話,可以去翻翻 《JavaScript 高級程序設計》第七章關于閉包的相關內(nèi)容。第一點當中存在一個小坑,就是將對象的方法賦予給一個變量的時候,其變?yōu)楹瘮?shù)觸發(fā),此時的 this 實際上是指向 window(非嚴格模式)。

那么,當函數(shù)中返回一個函數(shù),此時在對象當中調(diào)用該方法,其就相當于是函數(shù)觸發(fā),此時的 this,在不做任何上下文綁定的前提之下,其指向 window(非嚴格模式)。

 
 
  1. var name = 'Bob',
  2.     person = {
  3.         name: 'Alice',
  4.         sayName: function() {
  5.             console.log(this === person);    // true
  6.             return function() {
  7.                 console.log(this === person);    // false
  8.                 console.log(this === window);    // true
  9.                 console.log(this.name);          // Bob
  10.             };
  11.         }
  12.     };
  13. person.sayName()();

 當然,要解決這個問題的方法,很簡單,就是給他綁定一個上下文。

 
 
  1. var name = 'Bob',
  2.     person = {
  3.         name: 'Alice',
  4.         sayName: function() {
  5.             console.log(this === person);    // true
  6.             return function() {
  7.                 console.log(this === person);    // true
  8.                 console.log(this === window);    // false
  9.                 console.log(this.name);          // Alice
  10.             }.bind(this);
  11.         }
  12.     };
  13. person.sayName()();

 3 new 當中進行使用

我們知道在使用 new 方法創(chuàng)建對象的時候,會經(jīng)過如下這些個過程:

  • 創(chuàng)建對象,將 this 值賦予新的對象
  • 調(diào)用構(gòu)造函數(shù),為 this 添加屬性和方法
  • 返回 this 給當前的對象
 
 
  1. function Person(name, age) {
  2.     this.name = name;
  3.     this.age = age;
  4. }
  5. var person1 = new Person('Alice', 29);
  6. console.log(person1.name);    // Alice

 這里要記得使用 new 運算符,否則,其只能算是普通的調(diào)用,而不是創(chuàng)建一個新的實例對象。而當做普通函數(shù)調(diào)用的話,實際上即 第 2 種情況下,對函數(shù)普通調(diào)用,此時的 this 指向 window

 
 
  1. function Person(name, age) {
  2.     this.name = name;
  3.     this.age = age;
  4.     return this;
  5. }
  6. var person1 = Person('Alice', 29);
  7. console.log(person1.name);    // Alice
  8. console.log(window.name);     // Alice
  9. console.log(person1 === window);    // true

 這是正常情況下,this 會正確返回并且指向該對象,但是在構(gòu)造函數(shù)當中,如果返回了一個對象,那么 this 會指向返回的那個對象。

 
 
  1. function Person(name, age) {
  2.     this.name = name;
  3.     this.age = age;
  4.     return {
  5.         name: 'Bob'
  6.     };
  7. }
  8. var person1 = new Person('Alice');
  9. console.log(person1.name);    // Bob
  10. console.log(person1.age);     // undefined

 題外話,類似的,聯(lián)想到 var a = new Person(),則 a instanceof Person一定返回 true嗎?留給你們想一想咯。

4 使用 call、apply 或 bind 改變 this

在引用類型 Function當中,函數(shù)存在兩個方法屬性,call 和 apply,在 ECMAScript5當中,加入了 bind 方法。題外話,他們?nèi)邊^(qū)別,應該都知道了吧,不知道的加緊補習呀。

 
 
  1. var name = 'Bob';
  2. var person = {
  3.     name: 'Alice',
  4.     age: 29
  5. }
  6. function sayName() {
  7.     console.log(this.name);
  8. }
  9. sayName.call(person);    // Alice

 這里是使用了 call 方法來改變了 this的執(zhí)行環(huán)境,至于使用 apply,效果一樣,只是二者差別在于傳入?yún)?shù)的不同。

 
 
  1. func.call(context, arg1, arg2, ...)
  2. func.apply(context, [arg1, arg2, ...])

 使用 bind 方法進行上下文的改變,bind 方法與 call 和 apply有著本質(zhì)的不同,其不同點是,bind()函數(shù)返回的是一個新的函數(shù),即方法,而后兩者則都是立即執(zhí)行函數(shù),使用的時候即調(diào)用了該函數(shù),返回方法操作的結(jié)果。

并且,使用 bind()方法創(chuàng)建的 上下文,其為永久的上下文環(huán)境,不可修改,即使是使用 call 或者 apply方法,也無法修改 this所指向的值。

 
 
  1. var name = 'Bob';
  2. var person = {
  3.     name: 'Alice',
  4.     age: 29
  5. }
  6. function sayName() {
  7.     console.log(this.name);
  8. }
  9. var say = sayName.bind(person);
  10. say();        // Alice
  11. sayName();    // Bob

 5 箭頭函數(shù)

箭頭函數(shù)并不創(chuàng)建其自身的上下文,其上下文 this,取決于其在定義時的外部函數(shù)。

并且,箭頭函數(shù)擁有靜態(tài)的上下文,即一次綁定之后,便不可再修改,即使是用了 第 4 種用途當中的改變上下文的方法,也不為之動容。

 
 
  1. var num = [1, 2, 3];
  2. (function() {
  3.     var showNumber = () => {
  4.         console.log(this === num);    // true
  5.         console.log(this);            // [1, 2, 3]
  6.     }
  7.     console.log(this === num);        // true
  8.     showNumber();                     // true && [1, 2, 3]
  9.     showNumber.call([1, 2]);          // true && [1, 2, 3]
  10.     showNumber.apply([1, 2]);         // true && [1, 2, 3]
  11.     showNumber.bind([1, 2])();        // true && [1, 2, 3]
  12. }).call(num);

 由于箭頭函數(shù)的外部決定上下文以及靜態(tài)上下文等的特性,不太建議使用箭頭函數(shù)在全局環(huán)境下來定義方法,因為不能通過其他方法改變其上下文。這很蛋疼。

 
 
  1. function Period (hours, minutes) {  
  2.     this.hours = hours;
  3.     this.minutes = minutes;
  4. }
  5. Period.prototype.format = () => {  
  6.     console.log(this === window);    // => true
  7.     return this.hours + ' hours and ' + this.minutes + ' minutes';
  8. };
  9. var walkPeriod = new Period(2, 30);  
  10. console.log(walkPeriod.hours);
  11. walkPeriod.format();    // => 'undefined hours and undefined minutes' 

此時的 this 實際上是指向了 window,所以 this.hours 和 this.minutes實際上沒有聲明的,故為 undefined。

在全局環(huán)境下,還是選用 函數(shù)表達式 來進行函數(shù)的定義,可以保證正確的上下文環(huán)境

 
 
  1. function Period (hours, minutes) {  
  2.     this.hours = hours;
  3.     this.minutes = minutes;
  4. }
  5. Period.prototype.format = function() {  
  6.     console.log(this === walkPeriod);    // => true
  7.     return this.hours + ' hours and ' + this.minutes + ' minutes';
  8. };
  9. var walkPeriod = new Period(2, 30);  
  10. walkPeriod.format(); // '2 hours and 30 minutes' 

練習

 
 
  1. // 練習1
  2. var func = (function(a) {
  3.     this.a = a;
  4.     return function(a) {
  5.         a += this.a;
  6.         return a;
  7.     }
  8. })(function(a, b) {
  9.     return a;
  10. }(1, 2))
  11. func(4) // ?
  12. // 練習2
  13. var x = 10,
  14.     foo = {
  15.         x: 20,
  16.         bar: function() {
  17.             var x = 30;
  18.             return this.x;
  19.         }
  20.     }
  21. console.log(foo.bar());
  22. console.log((foo.bar)());
  23. console.log((foo.bar = foo.bar)());
  24. console.log((foo.bar, foo.bar)()); 

希望看完這篇文章,這兩個練習題,你是能夠做出來的呀~ 好好分析一下唄。如果不確定的話,可以在留言板上,咱們相互討論一下呀


當前標題:Knowthis,usethis!(總結(jié)this的常見用法)
網(wǎng)站網(wǎng)址:http://www.5511xx.com/article/cdieigj.html