日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

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

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
JavaScript之深入理解this

 定義

創(chuàng)新互聯(lián)主要從事成都網(wǎng)站設(shè)計、做網(wǎng)站、網(wǎng)頁設(shè)計、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)寧蒗,十載網(wǎng)站建設(shè)經(jīng)驗,價格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):18980820575

this是函數(shù)運行時自動生成的內(nèi)部對象,即調(diào)用函數(shù)的那個對象。(不一定很準確的定義,但還算通俗易懂) 在大多數(shù)情況下,this的值由函數(shù)調(diào)用方式?jīng)Q定,它不能在執(zhí)行期間賦值來設(shè)置,它在每次執(zhí)行下可能都有不同的值。

全局執(zhí)行環(huán)境(outside function)

在全局執(zhí)行環(huán)境中,this一直指向全局對象(global object),不管是在嚴格模式還是在非嚴格模式中。

代碼1 

 
 
 
  1. console.log(this.document === document);   //true  
  2. // 在瀏覽器中,window對象也就是全局對象(global object)  
  3. console.log(this === window);   //true  
  4. this.a  = 37;  
  5. console.log(window.a);   //37 

函數(shù)執(zhí)行環(huán)境(inside function)

在函數(shù)執(zhí)行環(huán)境中,this的值取決于函數(shù)的調(diào)用方式。

而函數(shù)的調(diào)用方式主要有4種:

  •  函數(shù)直接調(diào)用
  •  對象方法調(diào)用
  •  構(gòu)造函數(shù)調(diào)用
  •  call / apply / bind
  •  箭頭函數(shù)(ES6)

函數(shù)直接調(diào)用

下面的代碼在非嚴格模式執(zhí)行時,this的值會指向全局對象;而在嚴格模式中,this的值將會默認為undefined。

代碼2 

 
 
 
  1. /* 非嚴格模式 */  
  2. function f1 () {  
  3.   return this;  
  4. }  
  5. console.log(f1() === window);   //true  
  6. // in node;  
  7. console.log(f1() === global);   //true  
  8. /* 嚴格模式 */  
  9. function f2 () {  
  10.   'use strict'  
  11.   return this;  
  12.  
  13. console.log(f1() === undefined);   //true 

call / apply / bind 改變this的指向

call / apply

call和apply的用法很像,只是后面參數(shù)的傳入形式不同。

代碼3 

 
 
 
  1. function add(c, d) {  
  2.   return this.a + this.b + c + d;  
  3. }  
  4. var o = {a: 1, b: 3};  
  5. // call的第一個參數(shù) 是對象,也就是this的指向?qū)ο蟆:竺娴膮?shù)就是函數(shù)arguments對象的成員  
  6. add.call(o, 5, 7); // 1 + 3 + 5 + 7 = 16  
  7. // call的第一個參數(shù) 是對象,也就是this的指向?qū)ο?。后面的參?shù)是數(shù)組,數(shù)組里的成員也就是函數(shù)arguments對象成員  
  8. add.apply(o, [10, 20]); // 1 + 3 + 10 + 20 = 34 

使用call和apply時需要注意的是,當傳入的第一個參數(shù)的值不是對象時,JavaScript會嘗試使用ToObject 操作將其轉(zhuǎn)化為對象。

代碼4 

 
 
 
  1. function bar() {  
  2.   console.log(Object.prototype.toString.call(this));  
  3. }  
  4. bar.call(7); // [object Number] 

bind 方法

ECMAScript 5 引入了 Function.prototype.bind。調(diào)用f.bind(someObject)會創(chuàng)建一個與f具有相同函數(shù)體和作用域的函數(shù),但是在這個新函數(shù)中,this將永久地被綁定到了bind的第一個參數(shù),無論這個函數(shù)是如何被調(diào)用的。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

代碼5 

 
 
 
  1. function f() {  
  2.   return this.a;  
  3. }  
  4. var g = f.bind({a: 'azerty'}); //生成一個綁定函數(shù)g  
  5. console.log(g()); // azerty  
  6. var o = {a: 10, f: f, g: g};  
  7. console.log(o.f(), o.g());   //10, azerty  
  8. //需要注意的是,綁定函數(shù)不可以再bind  
  9. var h = g.bind({a: 'foo'});  
  10. console.log(h());  //azerty,不會變成foo 

對象方法調(diào)用

當以對象里的方法的方式調(diào)用函數(shù)時,它們的 this 是調(diào)用該函數(shù)的對象.

下面的例子中,當 o.f() 被調(diào)用時,函數(shù)內(nèi)的this將綁定到o對象。 

 
 
 
  1. var prop = 36;  
  2. var o = {  
  3.   prop: 37,  
  4.   bar: function() {  
  5.     return this.prop;  
  6.   }  
  7. };  
  8. console.log(o.bar());  //37 

構(gòu)造函數(shù)調(diào)用

代碼6 

 
 
 
  1. function Person(name, age) {  
  2.   this.name = name;  
  3.   this.age = age;  
  4.   this.introduce = function () {  
  5.     console.log('My name is ' + this.name + ', I\'m ' + this.age);  
  6.   };  
  7. }  
  8. var Joseph = new Person('Joseph', 19);  
  9. Joseph.introduce();  // "My name is Joseph, I'm 19" 

由上述代碼可以清晰的看到this與被新創(chuàng)建的對象綁定了。

注意:當構(gòu)造器返回的默認值是一個this引用的對象時,可以手動設(shè)置返回其他的對象,如果返回值不是一個對象,返回this。(這句話看起來比較難理解,我們看下一個例子)。

代碼7 

 
 
 
  1. function Fn2() {  
  2.   this.a = 9;  // dead code  
  3.   return {a: 10};  
  4. }  
  5. var o = new Fn2(); 
  6. console.log(o.a);  // 10 

這個例子說明了當構(gòu)造函數(shù)返回的是一個對象的話,此時this的值會變成此時返回的對象。‘this.a = 9’成了僵尸代碼。

箭頭函數(shù)

在箭頭函數(shù)( Arrow functions)中,this的值是封閉執(zhí)行環(huán)境決定的。在全局環(huán)境中,那么被賦值為全局對象。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions 

 
 
 
  1. var globalObject = this;  
  2. var foo = (() => this);  
  3. console.log(foo() === globalObject); // true 

更重要的是它與其他情況不同的是,不管函數(shù)如何調(diào)用,上面this的值一直都是全局對象。call / bind 也不能改變它的值。

代碼8 

 
 
 
  1. // 作為對象方法被調(diào)用  
  2. var obj = {foo: foo};  
  3. console.log(obj.foo() === globalObject); // true  
  4. // 嘗試用 call 改變this的值  
  5. console.log(foo.call(obj) === globalObject); // true //this的值并未變成obj  
  6. // 嘗試用 bind 改變this的值  
  7. foofoo = foo.bind(obj);  
  8. console.log(foo() === globalObject); // true 

案例

本文知識點都看完了。讓我們看幾個案例,檢查自己的掌握情況。

例1 

 
 
 
  1. var prop = 36;  
  2. var o = {  
  3.   prop: 37,  
  4.   bar1: function() {  
  5.     function foo1() {  
  6.       return this.prop;  
  7.     }  
  8.     return foo1;  
  9.   },  
  10.   bar2: function() {  
  11.     var foo2  = (() => this.prop); //ES6箭頭函數(shù)  
  12.     return foo2;  
  13.   } 
  14. };  
  15. console.log('result1:'+o.bar1()()); // result1 ?  
  16. console.log('result2:'+o.bar2()()); // result2 ?  
  17. var fn2 = o.bar2;  
  18. console.log('result3:'+fn2()()); // result3 ? 

先揭曉答案:例1 result1 = 36,result2 = 37,result3 = 36。我的理解是,在result1中,o.bar1()執(zhí)行導致foo函數(shù)return到了全局環(huán)境中,然后執(zhí)行就變成了在全局中執(zhí)行,所以得到的是全局中36的值。result2呢?因為this在箭頭函數(shù)中。它的值不會改變。所以this仍指向o。那為什么result3又重新變了呢?因為此時‘var fn2 = o.bar2’相當于重新定義了一個函數(shù),而this的值當然也就變?yōu)榱巳謱ο蟆?nbsp;

 
 
 
  1. // 相當于這樣  
  2. var fn2 = function() {  
  3.     function foo1() {  
  4.       return this.prop;  
  5.     }  
  6.     return foo1;  
  7.   }  
  8. fn2()(); 

例2 

 
 
 
  1. function sum(a,b) {  
  2.  return a+b;  
  3. };  
  4. var o = { 
  5.   num: 1,  
  6.   fn: function() {  
  7.         function handle() {  
  8.           return this.num = sum(this.num, this.num);  
  9.         }  
  10.     handle();  
  11.   }  
  12. };  
  13. console.log('result:'+o.fn());  // result ? 

同樣先揭曉答案:result = undefined,用控制臺可以看到此時this指向window,而不是o。這是個比較容易掉進去的坑(一般認為是當初的語言設(shè)計錯誤,被人詬病不少)??此坪瘮?shù)是由對象方法調(diào)用的,其實細心的話,我們可以看到。handle函數(shù)的執(zhí)行,前面的沒有對象的。這種情況下,this指向全局對象。解決辦法也很簡單。 

 
 
 
  1. // 1、取消 handle函數(shù)的定義,直接在對象的方法中使用this  
  2. fn2: function() {  
  3.     this.value = sum(this.value, this.value);  //2  
  4. },  
  5. ///2、使用變量保存外部函數(shù)的this。  
  6. fn3: function() {  
  7.     var that = this;   // that == o  
  8.     function handle() {  
  9.         that.value = add(that.value, that.value);  
  10.     }  
  11.     handle();  
  12. }  

標題名稱:JavaScript之深入理解this
當前URL:http://www.dlmjj.cn/article/ccoddoi.html