• <noscript id="ggggg"><dd id="ggggg"></dd></noscript>
    <small id="ggggg"></small> <sup id="ggggg"></sup>
    <noscript id="ggggg"><dd id="ggggg"></dd></noscript>
    <tfoot id="ggggg"></tfoot>
  • <nav id="ggggg"><cite id="ggggg"></cite></nav>
    <nav id="ggggg"></nav>
    成人黃色A片免费看三更小说,精品人妻av区波多野结衣,亚洲第一极品精品无码,欧美综合区自拍亚洲综合,久久99青青精品免费观看,中文字幕在线中字日韩 ,亚洲国产精品18久久久久久,黄色在线免费观看

    this解析 記錄分享

    2021-4-22    前端達人

    this指向的問題也是JavaScript中的難點之一了,也是面試常問的問題,很多時候對this指向的問題就很懵逼,明明應該是指向他,為什么又指向他了…所以我就學習了一下這方面的知識,整理了一下,希望能夠幫助大家

    為什么要用this?

    首先看一段代碼

    function identify(){
        return this.name.toUpperCase()
    }
    function speak(){
        var greeting = '你好,我是'+identify.call(this)
        console.log(greeting)
    }
    
    var me ={
        name:'kyle'
    }
    
    var you ={
        name:"reader"
    }
    identify.call(me) 
    identify.call(you) 
    
    speak.call(me) //?  你好,我是KYLE
    speak.call(you) //? 你好,我是READER 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    上面的這段代碼中可以從不同的上下文對象 me 和 you 中重復的使用identify函數和speak函數
    如果你不使用this的話 你就要顯式的將上下文對象作為參數傳遞進去,比如這樣:

    function identify(context){
        return context.name.toUpperCase()
    }
    function speak(context){
        var greeting = '你好,我是'+identify(context)
        console.log(greeting)
    }
    
    var me ={
        name:'kyle'
    }
    
    var you ={
        name:"reader"
    }
    identify(me)
    identify(you) 
    
    speak(me) 
    speak(you) 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    就像這樣,這樣看起來就不想上面那樣簡潔了,你要把一個對象傳來傳去的

    認識this

    剛見到this的時候 覺得this指向是這個函數自身,或者是函數的作用域,后來發現其實不是這樣的的,不過也不能說錯了,因為有些情況確實是這樣的,比如這樣:

    function foo(num){
        console.log('foo'+ num)
        this.count ++ 
    }
    foo.count = 0
    
    var i;
    for(i = 0;i<10;i++){
        if(i>5){
            foo.call(foo,i)
        }
    }
    console.log(foo.count) //4 這樣的話 this指向了foo本身  foo上面的count屬性++ 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    無法指向函數作用域

    var a = 3
    function foo() {
        var a = 2;
        bar.call(foo);
    }
    function bar() {
        console.log( this.a );
    }
    foo(); // undefined 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    我們要記住非常重要的一點:this是在運行的時候進行綁定的,而不是在定義的時候綁定,this的綁定跟函數聲明的位置沒有關系,主要是取決于函數的調用方式,想要找到this指向誰,我們就要看懂函數是怎么調用的。

    綁定規則

    1.默認綁定

    當一個獨立函數正常調用的時候,不帶任何修飾的調用

    // 非嚴格模式下
    var a = 3
    function foo(){
        console.log(this.a) //a
    }
    foo() 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    這種情況下 this.a被解析成了了 全局變量a,this指向是全局對象

    // 嚴格模式下
    var a = 3
    function foo(){
        "use strict" 
        console.log(this.a) //TypeError
    }
    foo() 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    嚴格模式下 this不會指向全局對象 this綁定的是undefined

    2.隱式綁定

    調用位置上是否有上下文對象

    function foo(){
        console.log(this.a)
    }
    var obj = {
        a:2,
        foo:foo
    }
    obj.foo() //2 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    調用位置會使用obj上下文對象來引用函數,foo被調用的時候 他的落腳點指向是obj對象,隱式綁定的規則就會把this指向這個上下文對象。所以this.a就跟 obj.a是一樣的

    function foo(){
        console.log(this.a)
    }
    var obj = {
        a:2,
        foo:foo
    }
    var obj2 = {
        a:3,
        obj:obj
    }
    obj2.obj.foo() //2 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    當多層調用的時候 只有最后一層才會影響函數的調用位置 比如上面這個 this綁定的還是 obj 而不是obj2

    注意

    隱式綁定會出現隱式丟失的問題,會失去綁定對象,最后應用默認綁定

    var a = 3;
    function foo(){
        console.log(this.a);
    }
    var obj = {
        a:2,
        foo:foo
    }
    var bar = obj.foo
    bar() //3 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    bar 是 obj.foo的一個引用 他引用的是foo函數本身,此時bar就是一個不帶任何修飾的函數調用 應用默認綁定

    var a = 3;
    function foo(){
        console.log(this.a);
    }
    var obj = {
        a:2,
        foo:foo
    }
    setTimeout( obj.foo, 100 ) //3
    setTimeout(function(fn){
        fn()
    },100,obj.foo) //3 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    參數傳遞也是一種隱式賦值,回調函數丟失this是非常常見的…

    3.顯式綁定

    隱式綁定的時候我們必須在一個對象內部包含一個指向函數的屬性,然后通過屬性間接引用函數,把這個this間接隱式的綁定到這個對象上
    如果我們不想在對象內部包含函數的引用 ,而想在某個對象上強制調用函數
    我們可以把這個函數綁定到對象的原型上,也算是不用再對象內部包含函數了吧…
    更好的辦法是我們可以使用函數的 call() apply() bind() 這種方法

    function foo(){
        console.log(this.a)
    }
    
    var obj = {
        a:2
    }
    foo.call(obj) //2
    foo.apply(obj) //2 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    如果你第一個參數傳入的是一個原始類型 比如字符串 布爾 數字作為綁定對象 這些原始類型會被轉換為 對象的形式 new String() new Number()…

    硬綁定

    Function.prototype.bind()
    function foo(){
        console.log(this.a)
    }
    
    var obj = {
        a:2
    }
    var obj2 = {
        a:3
    }
    var bar = foo.bind(obj)  //會返回一個硬編碼的新函數 他會把參數設置為this的上下文
    bar.call(obj2) //2  返回的新函數 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    有些api 方法 會提供一個可選參數 context 其作用跟bind一樣 確保你的回調函數使用指定的this 比如 array.forEach(fn,context)…

    4.new綁定

    使用new 來調用函數的時候會執行以下操作
    1.創建一個全新的對象
    2.這個新對象會被執行原型的鏈接
    3.新對象會綁定到函數調用的this
    4.如果沒有返回其他的對象,那么函數會自動返回這個對象

    function Foo(a){
        this.a = a
    }
    var bar = new Foo(2)
    console.log(bar.a) //2 
    
    • 1
    • 2
    • 3
    • 4
    • 5

    使用new 來調用Foo函數 會構造一個新對象并把它綁定到Foo調用中的this上 然后返回了

    優先級

    函數不帶任何修飾的時候單獨調用才會觸發默認綁定 所以說默認綁定是優先級最低的了

    那剩下三個規則哪個的優先級最高?

    顯示綁定跟隱式綁定比較

    function foo(){
        console.log(this.a)
    }
    var obj1 = {
        a:1,
        foo:foo
    }
    
    var obj2 = {
        a:2,
        foo:foo
    }
    obj1.foo() //1
    obj2.foo() //2
    
    obj1.foo.call(obj2) //2
    obj2.foo.call(obj1) //1 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    可以看到 顯示綁定的優先級還是更高一點

    new 綁定跟隱式綁定比較

    function foo(arg){
        this.a = arg
    }
    
    var obj1 ={
        foo:foo
    }
    var obj2 ={}
    
    obj1.foo(2)
    console.log(obj1.a) //2
    
    var bar = new obj1.foo(4)
    console.log(obj1.a) //2
    console.log(bar.a) //4 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    可以看到 new綁定的優先級比隱式綁定要高

    new 綁定跟顯示綁定比較

    new跟call apply無法一起使用 無法通過new foo.call(obj),試一下硬綁定

    在這里插入代碼片 
    
    • 1
    function foo(arg){
        this.a = arg
    }
    var obj1 ={}
    var bar = foo.bind(obj1)
    bar(3)
    console.log(obj1.a) //3
    
    var baz = new bar(4)
    console.log(baz.a) //4
    console.log(obj1.a) //3 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    new 調用bar修改了硬綁定時候的 函數的this new的優先級高一點

    所以我們可以根據下面的優先級規則進行判斷了

    1.函數是否在new中調用 是的話this綁定新創建的對象 var bar = new Foo()
    2.函數是否通過call apply 顯示綁定或者是 bind硬綁定 如果是的話this指向指定的對象 foo.call(obj)
    3.函數是否在某個上下文中調用 隱式綁定,如果是 this綁定那個上下文對象 注意綁定丟失的問題
    4.如果都不是 就是默認綁定非嚴格模式下綁定的是全局對象 嚴格模式下綁定的是undefined

    綁定例外

    1.將null和undefined作為call apply參數 作為this綁定對象的時候 這些值會被忽略 應用的是默認綁定

    var a =3
    function foo(){
        console.log(this.a) //3
    }
    foo.call(null) 
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2.箭頭函數

    function foo(){
        return ()=>{
            console.log(this.a)
        }
    }
    var obj1 = {
        a:3
    }
    var obj2 = {
        a:4
    }
    var bar = foo.call(obj1)
    bar.call(obj2) //3  this綁定的是obj1 而不是obj2!!! 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在看一個

    function foo(){
        setTimeout(()=>{
            console.log(this.a) //2
        },100)
    }
    var obj = {
        a:2
    }
    foo.call(obj) 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    箭頭函數不使用this綁定的四種規則,而是根據外層作用域來決定this的,外層作用域的this綁定的是什么 他的this就是什么





    轉自:csdn 論壇 作者:Selfimpr歐

    藍藍設計www.lzhte.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 平面設計服

    日歷

    鏈接

    個人資料

    藍藍設計的小編 http://www.lzhte.cn

    存檔

    主站蜘蛛池模板: 国产在线精品一区二区不卡麻豆| 国产YW8825免费观看网站| 免费人成黄页在线观看国际| 色综合色综合久久综合频道| 久久夜色精品国产噜噜麻豆| 国产黑色丝袜在线播放| 国产精品成人免费一区久久羞羞 | 亚洲国产综合自在线另类| 国产精品美女久久久久久大全| 福利网站导航| 国产又色又爽又黄的网站免费| 欧美在线观看高清一二三区| 欧洲女人裸体牲交视频| 国产午夜福利片无码视频| 97久久综合区小说区图片区| 日本一本一道久久香蕉免费| 成人黄色av免费观看| 亚洲AV成人无码久久精品四虎| 久久久久久久91精品免费观看| 白嫩丰满少妇美女无套| 亚洲人成网站7亚洲国国产自偷自偷免费一区 | 久久久精国产精品720| 无码人妻aⅴ一区二区三区蜜桃 | 最新国产精品第1页| 精品国产亚洲av麻豆尤物| 国产成人精品白浆免费视频试看| 国产精品香港三级国产AV| 国产成人啪精品视频网站午夜| 欧美人与动人物牲交| 狼友视频国产精品首页| 精品99在线黑丝袜| 中国国产xxxx免费视频| 成人福利在线免费观看| 中文无码日韩欧免费视频| 国产一区二区三区在线视频| 在线观看亚洲你懂得| 久久国产精品国产自线拍免费| 精品国产AV无码一区二区三区| 中文字幕成人| 精品无码一区二区三区AV| 都市激情第一页|