99偷拍视频精品区一区二,口述久久久久久久久久久久,国产精品夫妇激情啪发布,成人永久免费网站在线观看,国产精品高清免费在线,青青草在线观看视频观看,久久久久久国产一区,天天婷婷久久18禁,日韩动漫av在线播放直播

JavaScript中this指向有什么用-創新互聯

這篇文章給大家分享的是有關JavaScript中this指向有什么用的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

創新互聯建站憑借專業的設計團隊扎實的技術支持、優質高效的服務意識和豐厚的資源優勢,提供專業的網站策劃、網站設計制作、成都做網站、網站優化、軟件開發、網站改版等服務,在成都十余年的網站建設設計經驗,為成都上千余家中小型企業策劃設計了網站。

JavaScript 中的 this 指向問題有很多文章在解釋,仍然有很多人問。上周我們的開發團隊連續兩個人遇到相關問題,所以我不得不將關于前端構建技術的交流會延長了半個時候討論 this 的問題。

與我們常見的很多語言不同,JavaScript 函數中的 this 指向并不是在函數定義的時候確定的,而是在調用的時候確定的。換句話說, 函數的調用方式決定了 this 指向 。

JavaScript 中,普通的函數調用方式有三種:直接調用、方法調用和 new 調用。除此之外,還有一些特殊的調用方式,比如通過 bind() 將函數綁定到對象之后再進行調用、通過 call() 、 apply() 進行調用等。而 es6 引入了箭頭函數之后,箭頭函數調用時,其 this 指向又有所不同。下面就來分析這些情況下的 this 指向。

直接調用

直接調用,就是通過 函數名(...) 這種方式調用。這時候,函數內部的 this 指向全局對象,在瀏覽器中全局對象是 window ,在 NodeJs 中全局對象是 global 。

來看一個例子:

// 簡單兼容瀏覽器和 NodeJs 的全局對象
const _global = typeof window === "undefined" ? global : window;
function test() {
  console.log(this === _global);  // true
}
test();  // 直接調用

這里需要注意的一點是,直接調用并不是指在全局作用域下進行調用,在任何作用域下,直接通過 函數名(...) 來對函數進行調用的方式,都稱為直接調用。比如下面這個例子也是直接調用

(function(_global) {
  // 通過 IIFE 限定作用域
  function test() {
    console.log(this === _global); // true
  }
  test();   // 非全局作用域下的直接調用
})(typeof window === "undefined" ? global : window);

bind() 對直接調用的影響

還有一點需要注意的是 bind() 的影響。 Function.prototype.bind() 的作用是將當前函數與指定的對象綁定,并返回一個新函數,這個新函數無論以什么樣的方式調用,其 this 始終指向綁定的對象。還是來看例子:

const obj = {};
function test() {
  console.log(this === obj);
}
const testObj = test.bind(obj);
test();   // false
testObj(); // true

那么 bind() 干了啥?不妨模擬一個 bind() 來了解它是如何做到對 this 產生影響的。

const obj = {};
function test() {
  console.log(this === obj);
}
// 自定義的函數,模擬 bind() 對 this 的影響
function myBind(func, target) {
  return function() {
    return func.apply(target, arguments);
  };
}
const testObj = myBind(test, obj);
test();   // false
testObj(); // true

從上面的示例可以看到,首先,通過閉包,保持了 target ,即綁定的對象;然后在調用函數的時候,對原函數使用了 apply 方法來指定函數的 this 。當然原生的 bind() 實現可能會不同,而且更高效。但這個示例說明了 bind() 的可行性。

call 和 apply 對 this 的影響

上面的示例中用到了 Function.prototype.apply() ,與之類似的還有 Function.prototype.call() 。這兩方法的用法請大家自己通過鏈接去看文檔。不過,它們的第一個參數都是指定函數運行時其中的 this 指向。

不過使用 apply 和 call 的時候仍然需要注意,如果目錄函數本身是一個綁定了 this 對象的函數,那 apply 和 call 不會像預期那樣執行,比如

const obj = {};
function test() {
  console.log(this === obj);
}
// 綁定到一個新對象,而不是 obj
const testObj = test.bind({});
test.apply(obj);  // true
// 期望 this 是 obj,即輸出 true
// 但是因為 testObj 綁定了不是 obj 的對象,所以會輸出 false
testObj.apply(obj); // false

由此可見, bind() 對函數的影響是深遠的,慎用!

方法調用

方法調用是指通過對象來調用其方法函數,它是 對象.方法函數(...) 這樣的調用形式。這種情況下,函數中的 this 指向調用該方法的對象。但是,同樣需要注意 bind() 的影響。

const obj = {
  // 第一種方式,定義對象的時候定義其方法
  test() {
    console.log(this === obj);
  }
};
// 第二種方式,對象定義好之后為其附加一個方法(函數表達式)
obj.test2 = function() {
  console.log(this === obj);
};
// 第三種方式和第二種方式原理相同
// 是對象定義好之后為其附加一個方法(函數定義)
function t() {
  console.log(this === obj);
}
obj.test3 = t;
// 這也是為對象附加一個方法函數
// 但是這個函數綁定了一個不是 obj 的其它對象
obj.test4 = (function() {
  console.log(this === obj);
}).bind({});
obj.test();   // true
obj.test2();  // true
obj.test3();  // true
// 受 bind() 影響,test4 中的 this 指向不是 obj
obj.test4();  // false

這里需要注意的是,后三種方式都是預定定義函數,再將其附加給 obj 對象作為其方法。再次強調,函數內部的 this 指向與定義無關,受調用方式的影響。

方法中 this 指向全局對象的情況

注意這里說的是 方法 中而不是 方法調用 中。方法中的 this 指向全局對象,如果不是因為 bind() ,那就一定是因為不是用的方法調用方式,比如

const obj = {
  test() {
    console.log(this === obj);
  }
};
const t = obj.test;
t();  // false

t 就是 obj 的 test 方法,但是 t() 調用時,其中的 this 指向了全局。

之所以要特別提出這種情況,主要是因為常常將一個對象方法作為回調傳遞給某個函數之后,卻發現運行結果與預期不符——因為忽略了調用方式對 this 的影響。比如下面的例子是在頁面中對某些事情進行封裝之后特別容易遇到的問題:

class Handlers {
  // 這里 $button 假設是一個指向某個按鈕的 jQuery 對象
  constructor(data, $button) {
    this.data = data;
    $button.on("click", this.onButtonClick);
  }
  onButtonClick(e) {
    console.log(this.data);
  }
}
const handlers = new Handlers("string data", $("#someButton"));
// 對 #someButton 進行點擊操作之后
// 輸出 undefined
// 但預期是輸出 string data
很顯然 this.onButtonClick 作為一個參數傳入 on() 之后,事件觸發時,是對這個函數進行的直接調用,而不是方法調用,所以其中的 this 會指向全局對象。要解決這個問題有很多種方法
// 這是在 es5 中的解決辦法之一
var _this = this;
$button.on("click", function() {
  _this.onButtonClick();
});
// 也可以通過 bind() 來解決
$button.on("click", this.onButtonClick.bind(this));
// es6 中可以通過箭頭函數來處理,在 jQuery 中慎用
$button.on("click", e => this.onButtonClick(e));

不過請注意,將箭頭函數用作 jQuery 的回調時造成要小心函數內對 this 的使用。jQuery 大多數回調函數(非箭頭函數)中的 this 都是表示調用目標,所以可以寫 $(this).text() 這樣的語句,但 jQuery 無法改變箭頭函數的 this 指向,同樣的語句語義完全不同。

new 調用

在 es6 之前,每一個函數都可以當作是構造函數,通過 new 調用來產生新的對象(函數內無特定返回值的情況下)。而 es6 改變了這種狀態,雖然 class 定義的類用 typeof 運算符得到的仍然是 "function" ,但它不能像普通函數一樣直接調用;同時, class 中定義的方法函數,也不能當作構造函數用 new 來調用。

而在 es5 中,用 new 調用一個構造函數,會創建一個新對象,而其中的 this 就指向這個新對象。這沒有什么懸念,因為 new 本身就是設計來創建新對象的。

var data = "Hi";  // 全局變量
function AClass(data) {
  this.data = data;
}
var a = new AClass("Hello World");
console.log(a.data);  // Hello World
console.log(data);   // Hi
var b = new AClass("Hello World");
console.log(a === b);  // false

箭頭函數中的 this

先來看看 MDN 上對箭頭函數的說明

An arrow function expression has a shorter syntax than a function expression and does not bind its own this , arguments , super , or new.target . Arrow functions are always anonymous. These function expressions are best suited for non-method functions, and they cannot be used as constructors.

這里已經清楚了說明了,箭頭函數沒有自己的 this 綁定。箭頭函數中使用的 this ,其實是直接包含它的那個函數或函數表達式中的 this 。比如

const obj = {
  test() {
    const arrow = () => {
      // 這里的 this 是 test() 中的 this,
      // 由 test() 的調用方式決定
      console.log(this === obj);
    };
    arrow();
  },
  getArrow() {
    return () => {
      // 這里的 this 是 getArrow() 中的 this,
      // 由 getArrow() 的調用方式決定
      console.log(this === obj);
    };
  }
};
obj.test();   // true
const arrow = obj.getArrow();
arrow();    // true

示例中的兩個 this 都是由箭頭函數的直接外層函數(方法)決定的,而方法函數中的 this 是由其調用方式決定的。上例的調用方式都是方法調用,所以 this 都指向方法調用的對象,即 obj 。

箭頭函數讓大家在使用閉包的時候不需要太糾結 this ,不需要通過像 _this 這樣的局部變量來臨時引用 this 給閉包函數使用。來看一段 Babel 對箭頭函數的轉譯可能能加深理解:

// ES6
const obj = {
  getArrow() {
    return () => {
      console.log(this === obj);
    };
  }
}
// ES5,由 Babel 轉譯
var obj = {
  getArrow: function getArrow() {
    var _this = this;
    return function () {
      console.log(_this === obj);
    };
  }
};

另外需要注意的是,箭頭函數不能用 new 調用,不能 bind() 到某個對象(雖然 bind() 方法調用沒問題,但是不會產生預期效果)。不管在什么情況下使用箭頭函數,它本身是沒有綁定 this 的,它用的是直接外層函數(即包含它的最近的一層函數或函數表達式)綁定的 this 。

感謝各位的閱讀!關于“JavaScript中this指向有什么用”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

另外有需要云服務器可以了解下創新互聯建站www.yijiale78.com,海內外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業上云的綜合解決方案,具有“安全穩定、簡單易用、服務可用性高、性價比高”等特點與優勢,專為企業上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。

網頁題目:JavaScript中this指向有什么用-創新互聯
網站地址:http://www.yijiale78.com/article48/dpcghp.html

成都網站建設公司_創新互聯,為您提供建站公司虛擬主機企業網站制作網站制作網站改版網站導航

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

網站托管運營