国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

深入理解JavaScript中的this指向

不知名網友 / 901人閱讀

摘要:和作用域判別失敗相關,而代表作用域判別成功,但是對結果的操作是非法的不合理的。在中,構造函數只是使用操作符時被調用的函數,它們并不屬于一個類,也不會實例化一個類。也就是說,中,不存在所謂的構造函數,只有對函數的構造調用。

與其他語言相比,js中的this有所不同,也是比較頭疼的問題。在參考了一些資料后,今天,就來深入解析一下this指向問題,有不對的地方望大家指出。

為什么要用this

對于前端開發者來說,this是比較復雜的機制,那么為什么要花大量時間來學習呢,先來看一段代碼。
如果不使用this,要給identify( )和speak( )顯式傳入一個對象:

function identify(context) {
    return context.name.toUpperCase();
}
function speak(context) {
    var greeting = "Hello, I"m" + identify(context);
    console.log(greeting);
}
identify(you);
speak(me);

可以看到,speak( )里面直接寫了identify( )的函數名,然而,隨著使用模式越來越復雜,顯式傳遞的上下文會讓代碼變得混亂,尤其體現在面向對象中。
顯然,this提供了一種方式來隱式“傳遞”一個對象的引用,更加簡潔,易于復用。

this的誤解 1. this指向函數本身

記錄函數foo被調用的次數:

function foo(num) {
    console.log("foo:" + num);
    
    // 記錄次數
    this.count++;
}

foo.count = 0;

var i;

for (i = 0; i < 10; i++) {
    if (i > 5) {
        foo(i);
    }
}

// foo: 6
// foo: 7
// foo: 8
// foo: 9

//foo被調用了多少次?
console.log(foo.count); // 0

從前兩次的console.log( )可以看出,foo確實被調用了4次,但是foo.count仍然為0,顯然this指向函數本身的理解是錯誤的。

2. this指向函數作用域

要明確的是,this在任何情況下都不指向函數的詞法作用域。因為,作用域“對象”無法通過JavaScript代碼訪問,它存在于JavaScript引擎內部。
下面的代碼試圖使用this來隱式引用函數的詞法作用域,沒有成功:

function foo() {
    var a = 2;
    this.bar();
}
function bar() {
    console.log(this.a);
}
foo(); // ReferenceError: a is not defined

直接報出了訪問不到foo( )中的a。ReferenceError和作用域判別失敗相關,而TypeError代表作用域判別成功,但是對結果的操作是非法的、不合理的。

this是什么

排除了以上兩個誤解之后,來看一下this到底是什么。
this是運行時綁定的,它和函數聲明的位置沒有任何關系,只取決于函數的調用方式。當一個函數被調用時,會創建一個活動記錄(執行上下文),這個記錄包含函數在哪里被調用,函數的調用方式、傳入的參數等,this就是這個記錄的一個屬性,在函數執行的過程中用到。即,this總是指向調用它所在方法的對象

1. 在瀏覽器中,調用方法沒有明確對象時,this指向window
function foo() {
    console.log(this.a);
}

var a = 2;

foo(); // 2

在全局中聲明變量a = 2,然后在全局中直接調用foo( ),this指向了全局對象,得到a的值。
要注意的是,在嚴格模式(strict mood)下,如果this沒有被執行環境定義,那它將綁定為undefined。

function foo() {
    "use strict";
    
    console.log(this.a);
}

var a = 2;

foo(); // TypeError: this is undefined

在嚴格模式下,調用foo( )不影響this綁定。

function foo() {
    console.log(this.a);
}

var a = 2;

(function() {
    "use strict";
    
    foo(); // 2
})();
2. 在瀏覽器中,setTimeout、setInterval和匿名函數執行時的當前對象是全局對象window
function foo() {
    console.log(this.a);
}

var obj = {
    a: 2,
    foo: foo
};

var a = "global";

setTimeout(obj.foo, 100); // "global"

JavaScript中的setTimeout( )的實現和下面偽代碼相似:

function setTimeout(fn, delay) {
    // 等待delay毫秒
    fn(); // 調用函數
}
3. apply / call / bind可以強制改變this指向
function foo() {
    console.log(this.a);
}

var obj = {
    a: 2
};

foo.call(obj); // 2
foo.apply(obj); // 2
foo.bind(obj); // 2

call和apply的區別在于第二個參數,call是把args全部列出來,用“,”分隔,而apply是一個類數組。call、apply是硬綁定,通過硬綁定的函數不能再修改它的this。

function foo() {
    console.log(this.a);
}

var obj = {
    a: 2
};

var bar = function() {
    foo.call(obj);
}

bar(); // 2
setTimeout(bar, 100); // 2

bar.call(window); // 2

函數foo( )內部手動調用了foo.call(obj),把foo的this強制綁定到了obj,所以后面即使又把bar( )綁定到了window,還是無法改變this指向。

4. new操作符改變this指向

在傳統的面向對象語言中,會使用new初始化類,然而在JavaScript中new的機制和面向對象語言完全不同。在js中,構造函數只是使用new操作符時被調用的函數,它們并不屬于一個類,也不會實例化一個類。也就是說,js中,不存在所謂的“構造函數”,只有對函數的“構造調用”。

function foo(a) {
    this.a = a;
}

var bar = new foo(2);
console.log(bar.a); // 2

使用new調用foo( ),會構造一個新對象并把它綁定到foo( )調用中的this上。

優先級

既然有那么多可以改變this的指向,那么它們的優先級是怎么樣的呢,記住這句話:范圍越小,優先級越高。可以按照下面的順序來判斷:

判斷函數是否在new中調用過:

var bar = new foo();

判斷函數是否通過call、apply、bind綁定過:

var bar = foo.call(obj);

判斷函數是否在某個上下文對象中調用過:

var bar = obj.foo();

如果以上情況均不存在,那么在嚴格模式下,綁定到undefined,否則綁定到全局對象:

var bar = foo();

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/103071.html

相關文章

  • 我對JavaScriptthis的一些理解

    摘要:匿名函數的執行環境具有全局性,因此它的對象通常指向。如果對此有疑惑,可以看知乎上的答案知乎匿名函數的指向為什么是作為對象方法的調用,指向該對象當函數作為某個對象的方法調用時,就指這個函數所在的對象。 因為日常工作中經常使用到this,而且在JavaScript中this的指向問題也很容易讓人混淆一部分知識。 這段時間翻閱了一些書籍也查閱了網上一些資料然后結合自己的經驗,為了能讓自...

    focusj 評論0 收藏0
  • Javascript深入理解this作用域問題以及new/let/var/const對this

    摘要:理解作用域高級程序設計中有說到對象是在運行時基于函數的執行環境綁定的在全局函數中,等于,而當函數被作為某個對象調用時,等于那個對象。指向與匿名函數沒有關系如果函數獨立調用,那么該函數內部的,則指向。 理解this作用域 《javascript高級程序設計》中有說到: this對象是在運行時基于函數的執行環境綁定的:在全局函數中,this等于window,而當函數被作為某個對象調用時,t...

    snowLu 評論0 收藏0
  • JavaScriptthis指向深入解析

    普通函數的this指向 簡單說說 首先,按照慣例,我們先舉個栗子: var bar = 2; function foo() { this.bar = 1; this.getBar = function() { console.log(this.bar); } } var test = new foo(); var getBar = test.getBar; test.getB...

    AlphaGooo 評論0 收藏0
  • 深入理解 Javascriptthis

    摘要:深入淺出的理解問題的由來寫法一寫法二雖然和指向同一個函數,但是執行結果可能不一樣。該變量由運行環境提供。所以,就出現了,它的設計目的就是在函數體內部,指代函數當前的運行環境。 深入淺出this的理解 問題的由來 var obj = { foo: function(){} } var foo = obj.foo; // 寫法一 obj.foo(); // 寫法二 foo...

    OnlyMyRailgun 評論0 收藏0
  • 深入理解JavaScript(三):獲取數組中的最大值方法(this,apply)

    摘要:三個方法的作用,都是改變的指向,只是用法稍微有些區別什么是既不指向函數自身,也不指函數的詞法作用域。它在函數定義的時候是確定不了的在函數被調用時才發生的綁定,也就是說具體指向什么,取決于你是怎么調用的函數。 1.排序法 思路:給數組先排序(由大到小排序),第一項就是最大值 let arr = [1,5,6,7,9,20,40,2,3]; let max1 = arr.sort(func...

    canopus4u 評論0 收藏0

發表評論

0條評論

不知名網友

|高級講師

TA的文章

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