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

資訊專欄INFORMATION COLUMN

淺談-this

archieyang / 1233人閱讀

摘要:回調(diào)函數(shù)中調(diào)用在回調(diào)函數(shù)中一般有兩種情況回調(diào)函數(shù)為匿名函數(shù)時(shí),回調(diào)函數(shù)的會指向,需要對回調(diào)函數(shù)。回調(diào)函數(shù)為箭頭函數(shù)時(shí),回調(diào)函數(shù)的會指向他的直接上層。

淺談-this

this簡單而又神秘,使用場景多變而又復(fù)雜,這造就了它成為了初級javascript開發(fā)人員不愿接觸的東西,高級javascript都想探究的東西。文本亦是對this的致敬。

this是什么?
this是當(dāng)前執(zhí)行環(huán)境的上下文,通常由函數(shù)的調(diào)用方式?jīng)Q定其值。

this的原理

首先,從函數(shù)的調(diào)用開始

函數(shù)的調(diào)用一般有三種情況(ES5中)

1.foo(p1,p2);
2.obj.foo(p1,p2);
3.foo().call(context,p1,p2);//或者apply

通常情況下,大部分童鞋常用的都是前兩種方式,只有在不得不綁定context的情況下才會使用第三種。其中,第三種方式,才是函數(shù)調(diào)用的正確方式。

foo().call(context,p1,p2);

之所以,我們在使用前兩種方式也能正常的運(yùn)行,這其實(shí)就是一種語法糖而已,在js運(yùn)行機(jī)制中,會把前兩種調(diào)方式,當(dāng)做下面的方式進(jìn)行處理

foo(p1, p2) 等價(jià)于  
foo.call(undefined, p1, p2)

 obj.foo(p1, p2) 等價(jià)于
 obj.foo.call(obj, p1, p2)  

因此,如果我們以后再調(diào)用函數(shù)時(shí),能準(zhǔn)確的找到context,就可以唯一的確認(rèn)this的值

this的使用場景

3.1 全局環(huán)境使用

 無論是否在嚴(yán)格模式下,在全局執(zhí)行環(huán)境中(在任何函數(shù)體外部)this 都指向全局對象。

// 在瀏覽器中, window 對象同時(shí)也是全局對象:
console.log(this === window); // true
var a=1;
console.log(this.a) //1
console.log(window.a) //1

3.2 普通函數(shù)中調(diào)用

  在非嚴(yán)格模式下,且this的值沒有被調(diào)用函數(shù)設(shè)置,this 的值默認(rèn)指向全局對象。
   funnction func(){
     console.log(this)
   }
   //瀏覽器環(huán)境中
   func()  // window
   //node環(huán)境中
   func()  // global
  
  在嚴(yán)格模式下,this的值如果不設(shè)置,就是是undefined
  
   funnction func(){
     "use strict"
     console.log(this)
   }
  func() === undefined; // true

3.3 作為對象中的方法調(diào)用

var obj={

    name:"我是對象obj",
    ofun:function(){
    console.log(this.name)
    }
}
var name="我是全局name";
var func= obj.ofun;
obj.ofun(); //我是對象obj
func(); //我是全局name

這里有兩點(diǎn)需要注意:

   1.函數(shù)作為對象的方法進(jìn)行調(diào)用時(shí),this指向當(dāng)前的對象。                  
   2.對象中的函數(shù)方法名存儲的僅是一個(gè)函數(shù)的地址(地址中會有該函數(shù)的屬性:[[value]、[[writable]]、[[enumerable]]、[[congifable]])
   當(dāng)把一個(gè)對象的方法賦值給另一個(gè)變量(例如:func)時(shí),引擎會將函數(shù)多帶帶保存在內(nèi)存中,然后再將函數(shù)的地址賦值給foo屬性的value屬性。

3.4 構(gòu)造函數(shù)中使用

  this在構(gòu)造函數(shù)中使用,值為實(shí)例化的對象

function Fun(name){
     this.name=name;
     this.speak=function(){
        console.log(this.name);
     }
   }
   var fun1=new Fun("jack");
   fun1.speak();
   var fun2=new Fun("rose");
   fun2.speak();//rose

3.5 bind/call/apply

this再被bind/call/apply強(qiáng)制綁定上下文執(zhí)行環(huán)境時(shí),屬于硬綁定。
 
  function foo(somerthing){
     console.log(this.a);
   }
   var obj={
     a:2
   }
   var bar = function(){
     foo.call(obj);
   };
   bar(); //2
   //硬綁定的bar不可能再修改它的this
   bar.call(window);//2
 }

硬綁定的典型應(yīng)用場景就是創(chuàng)建一個(gè)包裹函數(shù),傳入所有的參數(shù)并返回接收到的所有值;

  function foo(somerthing){
     console.log(this.a,something);
     return this.a +something;
   }
   var obj={
     a:2
   }
   var bar = function(){
     return foo.apply(obj,arguments);
   };
   var b=bar(3);// 2 3
   console.log(b);//5

由于硬綁定是一種非常常用的模式,所以在ES5中提供了內(nèi)置的方法Function.prototype.bind,它的用法如下;

   function foo(somerthing){
     console.log(this.a,something);
      return this.a +something;
   }
   var obj={
     a:2
   }
   var bar=foo.bind(obj);
   var b=bar(3);// 2 3
   console.log(b);//5

call,apply,bind方法的區(qū)別:

  a:第一個(gè)參數(shù)都是要綁定的上下文執(zhí)行環(huán)境,即this的值。
  b:都可在函數(shù)調(diào)用時(shí)傳遞參數(shù)。call,bind方法需要直接傳入,而apply方法需要以數(shù)組的形式傳入。
  c:call,apply方法是在調(diào)用之后立即執(zhí)行函數(shù),而bind方法沒有立即執(zhí)行,需要將函數(shù)再執(zhí)行一遍。有點(diǎn)閉包的味道。
  d:改變this對象的指向問題不僅有call,apply,bind方法,也可以使用that/self等變量來固定this的指向。

3.6 回調(diào)函數(shù)中調(diào)用

  在回調(diào)函數(shù)中一般有兩種情況:
   1. 回調(diào)函數(shù)為匿名函數(shù)時(shí),回調(diào)函數(shù)的this會指向window,需要對回調(diào)函數(shù)bind(this)。
   2. 回調(diào)函數(shù)為箭頭函數(shù)時(shí),回調(diào)函數(shù)的this會指向他的直接上層。
   

  var obj = {
      name: "test for call-func",
      ofun: function(){
            //undefined 丟失
            setTimeout(function(){
              console.log(this.name)
            }, 100);
           //work well 硬綁定
            setTimeout(function(){
               console.log(this.name)
            }.bind(this), 100);//test for call-func
           // arrow function  test for call-func
           setTimeout( () => console.log(this.id), 100)
      }
    };

    obj.ofun();

3.7 自執(zhí)行函數(shù)
自執(zhí)行或者立即執(zhí)行函數(shù)中的this指向Window
首先自執(zhí)行函數(shù)的幾種調(diào)用方式

//常見的有兩種:
(function(){})()    (function(){}())//w3c推薦方式
//只有表達(dá)式才能被執(zhí)行符號()執(zhí)行
+function test(){}();//+ - ! =等運(yùn)算符可以使前面的函數(shù)成為表達(dá)式,加上后面()可立即執(zhí)行。
//函數(shù)聲明無法立即執(zhí)行一個(gè)函數(shù),但是函數(shù)表達(dá)式可以
var a = function(){}();//這種是函數(shù)表達(dá)式,后面有()可以立即執(zhí)行。成為一個(gè)立即執(zhí)行函數(shù)。
var obj = {
    number: 3,
    xxx: (function () {
        console.log(this + "--")//立即執(zhí)行函數(shù)中的this指向window,因?yàn)榱⒓磮?zhí)行函數(shù)是window調(diào)用的
        console.log(this.number + "~~~")//刪除上面一行,此處this.number返回undefined
        return function () {
            console.log(this.number + "】")
            this.number += 7;
            console.log(this + "+")
        }
    })()
}

obj.xxx() //相當(dāng)于obj.xxx.call(),所以此處的this指向obj
console.log(obj.number) //10

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

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

相關(guān)文章

  • 淺談js中的this

    摘要:相信很多剛剛學(xué)習(xí)的新手都會有同感,當(dāng)看一段代碼時(shí),發(fā)現(xiàn)里面有很多,但是這些到底是指向哪里卻沒有那么清楚,為了搞清楚這些到底是什么情況,特地花點(diǎn)時(shí)間總結(jié)如下幾點(diǎn)最普遍的表示全局對象表示全局對象輸出為解析設(shè)置全局變量初始值為,當(dāng)調(diào)用函數(shù)之后改變 相信很多剛剛學(xué)習(xí)js的新手都會有同感,當(dāng)看一段js代碼時(shí),發(fā)現(xiàn)里面有很多this,但是這些this到底是指向哪里卻沒有那么清楚,為了搞清楚這些th...

    GHOST_349178 評論0 收藏0
  • 淺談Javascript閉包中作用域及內(nèi)存泄漏問題

    摘要:將作用域賦值給變量這里的作用域是,而不是將作用域賦值給一個(gè)變量閉包返回瀏覽器中內(nèi)存泄漏問題大家都知道,閉包會使變量駐留在內(nèi)存中,這也就導(dǎo)致了內(nèi)存泄漏。 上一章我們講了匿名函數(shù)和閉包,這次我們來談?wù)勯]包中作用域this的問題。 大家都知道,this對象是在運(yùn)行時(shí)基于函數(shù)的執(zhí)行環(huán)境綁定的,如果this在全局就是[object window],如果在對象內(nèi)部就是指向這個(gè)對象,而閉包卻是在運(yùn)行...

    source 評論0 收藏0
  • 淺談OOP Javascript [1]

    摘要:工廠模式優(yōu)點(diǎn)集中實(shí)例化,可以傳參等缺點(diǎn)分不清屬于哪個(gè)對象我們先來談?wù)剝?yōu)點(diǎn),看例子集中實(shí)例化返回實(shí)例化對象返回返回不難看出,工廠模式比上面的例子減少了很多代碼。 ECMAscript開發(fā)的兩種模式:1.過程化 2.OOP(面向?qū)ο? 面向?qū)ο蟮恼Z言有一個(gè)標(biāo)志,那就是類的概念,而通過類可以創(chuàng)建任意多個(gè)具有相同屬性的方法的對象。但是ECMAscript中沒有類的概念! 又談作用域 首先...

    xinhaip 評論0 收藏0
  • 淺談原型式繼承、借助構(gòu)造函數(shù)、組合方式繼承

    摘要:想要解決這樣的問題的話,可以借助構(gòu)造函數(shù)也可以叫做偽造對象或經(jīng)典繼承。這種方式實(shí)現(xiàn)非常簡單,就是在子對象的構(gòu)造函數(shù)中調(diào)用父對象的構(gòu)造函數(shù)。 原型式繼承 原型式繼承,就是一定一個(gè)函數(shù),該函數(shù)中創(chuàng)建一個(gè)臨時(shí)性的構(gòu)造函數(shù),將作為參數(shù),傳入的對象作為這個(gè)構(gòu)造函數(shù)的原型,最后返回這個(gè)構(gòu)造函數(shù)的實(shí)例對象 /*定義函數(shù):用于實(shí)現(xiàn)對象之間的繼承 參數(shù): obj:表示繼承關(guān)系中的父級對象...

    wangjuntytl 評論0 收藏0
  • 淺談在JS中使用Object的watch方法監(jiān)控對象屬性

    摘要:對其的解釋為概述監(jiān)視一個(gè)對象的某個(gè)屬性是否發(fā)生變化在該屬性變化時(shí)立即觸發(fā)指定的回調(diào)函數(shù)語法參數(shù)想要監(jiān)視值是否發(fā)生變化的指定對象的某個(gè)屬性的屬性名稱當(dāng)指定的屬性發(fā)生變化時(shí)執(zhí)行的回調(diào)函數(shù)在內(nèi)查看其聲明如下可以看到這兩個(gè)方法是只針對內(nèi)核的瀏覽器使 MDN 對其的解釋為: 概述: 監(jiān)視一個(gè)對象的某個(gè)屬性是否發(fā)生變化,在該屬性變化時(shí)立即觸發(fā)指定的回調(diào)函數(shù). 語法: object....

    noONE 評論0 收藏0

發(fā)表評論

0條評論

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