JavaScript this的指向和改變this指向的方法

一、js 中 this 是什么

this 是函數(shù)執(zhí)行時(shí)所在的上下文環(huán)境

二、this 的指向

js 全局對(duì)象:在 html 頁面中引入的 js 文件 全局對(duì)象 是 window 對(duì)象,使用 node 命令執(zhí)行 js 文件 全局對(duì)象 是 global 對(duì)象

1. 在 js 文件外層 this 指向 全局對(duì)象

console.log(this); // 全局對(duì)象

2. 在函數(shù)中 this 指向

  1. 在嚴(yán)格模式下,this 指向的是 undefined
"use strict";
function a() {
  console.log(this); // undefined
}
a();
  1. 在非嚴(yán)格模式下,如果把函數(shù)當(dāng)作構(gòu)造函數(shù)使用:this 指向這個(gè)構(gòu)造函數(shù)創(chuàng)建的實(shí)例對(duì)象
// 構(gòu)造函數(shù)
function A() {
  this.name = "alias";
  this.age = 20;
  this.show = ()=>{
    console.log(this);
  }
}
console.log(new A()); // {name: 'alias', age: 20}
new A().show() // {name: 'alias', age: 20}
console.log(window.age); // undefined , 說明構(gòu)造函數(shù)中的this不指向全局對(duì)象
  1. 在非嚴(yán)格模式下,如果把函數(shù)當(dāng)作普通函數(shù)調(diào)用:this 指向函數(shù)運(yùn)行時(shí)所在的上下文環(huán)境
    即:在 script 標(biāo)簽外層的調(diào)用函數(shù):this 指向全局對(duì)象,以對(duì)象的方法的方式調(diào)用函數(shù):this 指向方法所在的對(duì)象
// 外層直接調(diào)用:this 是全局對(duì)象
function a() {
  this.username = "alias";
  this.password = 123456;
}
a();
console.log(window.username); // alias
console.log(this.username); // alias
// 對(duì)象方法:this 的指向取決于調(diào)用對(duì)象方法的方式
const objB = {
  xcxv: "xcxv",
  getXcxv() {
    console.log(this.xcxv);
  },
};

objB.getXcxv(); // alias , 以對(duì)象的方法的方式調(diào)用:this 指向?qū)ο蠓椒ㄋ诘膶?duì)象

const bbb = objB.getXcxv;
bbb(); // undefined, 將對(duì)象的方法取出并在 script 標(biāo)簽外層調(diào)用:this 指向全局對(duì)象
  1. 在事件中 this 指向當(dāng)前事件所在的 dom 元素
<div onclick="show(this)">hello world</div>
<script>
  function show(params) {
    console.log(params); // 當(dāng)前dom元素 <div onclick="show(this)">hello world</div>
  }
</script>

三、臨時(shí)改變 this 指向的三個(gè)方法 call、apply、bind

  1. call、apply、bind 三者都可改變 this 的指向,且都只是臨時(shí)的改變 this 的指向
  2. call 和 bind 方法傳參方式一樣,第一個(gè)參數(shù)是 this 指向的實(shí)例對(duì)象,其他是方法參數(shù),以逗號(hào)隔開,區(qū)別是 bind 方法不立即執(zhí)行,需要以方法的方式調(diào)用
  3. apply 方法,第一個(gè)參數(shù)是 this 指向的實(shí)例對(duì)象,其他是方法參數(shù),放在數(shù)組中以逗號(hào)隔開
  1. call、apply、bind 方法使用示例
// 讓 A 的 this 指向 B,并調(diào)用 A 函數(shù),此時(shí) A 和 B 的實(shí)例屬性會(huì)合并
function A(p1, p2) {
  this.a = 'AAAAA' 
  this.p1 = p1
  this.p2 = p2
  console.log(this);
}
var B = { b: "BBBBB" };
A.call(B, "x", "xx"); // 結(jié)果: { name: 'B' } x xx
A.apply(B, ["x", "xx"]); // 結(jié)果: { name: 'B' } x xx
A.bind(B, "x", "xx")(); // 結(jié)果: { name: 'B' } x xx

new A() //結(jié)果: {a: 'AAAAA', p1: undefined, p2: undefined},說明改變 this 指向只是臨時(shí)的
  1. 在借用構(gòu)造函數(shù)繼承中,使用 call、apply,讓子類繼承父類的實(shí)例屬性
// 父類
function A() {
    this.name = "AAAAAAA";
    this.age = 18;
}
// 子類
function B() {
    this.BBBBB = "BBBBB"; // 與父類不同名的屬性可以寫在  A.call(this) 上面

    A.call(this)  // 將父類 A 的 this 指向子類 B 實(shí)例對(duì)象,并執(zhí)行 A,此時(shí) A 和 B 的實(shí)例屬性會(huì)合并,也就是B繼承了A實(shí)例屬性(函數(shù)中this總是指向?qū)嵗龑?duì)象)
    
    this.name = "B"; // 與父類同名的屬性要寫在 A.call(this) 下面,否則會(huì)在 A.call(this) 時(shí)被父類屬性覆蓋掉
}
console.log(new (A)); // {name: 'AAAAAAA', age: 18}
console.log(new (B)); // {BBBBB: 'BBBBB', name: 'B', age: 18}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容