第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

全部開發(fā)者教程

JavaScript 入門教程

JavaScript this

當(dāng)前執(zhí)行代碼的環(huán)境對象,在非嚴(yán)格模式下,總是指向一個對象,在嚴(yán)格模式下可以是任意值。(MDN)

this 指向的是當(dāng)前的代碼上下文環(huán)境,所以不同情況下的 this 指向也不同。

1. 全局下的 this

在全局環(huán)境下,this 指向全局對象。

全局對象和宿主環(huán)境相關(guān),在瀏覽器下,全局對象就是 window 對象,在 node.js 中,全局對象是 global 對象。

window === this; // 輸出:true

圖片描述

新的標(biāo)準(zhǔn)提供了 globalThis 關(guān)鍵字來獲取全局對象,這樣就能抹平宿主的差異來操作處理全局對象了。

2. 函數(shù)中的 this

函數(shù)在不同情況下,其 this 的指向也不同。

2.1 對象下的方法

方法也是一個函數(shù),如果通過對象調(diào)用一個函數(shù),函數(shù)的 this 就會指向這個對象。

var person = {
  age: 14,
  name: '鴿子王',
  skill: '放鴿子',
  say: function() {
    console.log('來一段自我介紹:');
    console.log('我是' + this.name);
    console.log('我今年' + this.age + '歲');
    console.log('我最擅長' + this.skill);
  },
};

person.say();

圖片描述

say函數(shù)作為對象下的方法,在被調(diào)用后,其 this 指向的是他所在的對象,在這里就是 person 對象。

2.2 原型鏈上方法的 this

原型鏈上的方法,this 指向的也是調(diào)用該方法的對象。

var __proto__ = {
  sum: function() {
    return this.number1 + this.number2;
  },
};

var object = Object.create(__proto__);

object.number1 = 1;
object.number2 = 2;

console.log(
  object.sum(),
); // 輸出:3

圖片描述

Object.create 做就就是將參數(shù)作為原型,創(chuàng)建一個對象。

所以 object 的第一原型就是 __proto__ 對象。

number1number2 都是 object 變量的屬性,但卻可以被 sum 方法中的 this 訪問到,所以在原型鏈的方法中,this 指向的就是調(diào)用該方法的對象。

2.3 getter / setter 下的 this

gettersetter 下的 this 也會指向調(diào)用該 gettersetter 的對象。

var object = {
  _name: '鴿子王',

  get name() {
    return this._name;
  },

  set name(val) {
    console.log(val);
    this._name = val;
  }
};

console.log(object.name); // 輸出:鴿子王

object.name = '鴿子天王'; // 輸出:鴿子天王

console.log(object.name); // 輸出:鴿子天王

圖片描述

gettersetter 本質(zhì)上也可以理解成兩個函數(shù),作為對象下的函數(shù),在調(diào)用的時候 this 也會指向該對象。

2.4 作為 DOM 節(jié)點的事件處理器

作為 DOM 節(jié)點的事件處理器的時,函數(shù)的 this 會指向這個 DOM 對象。

<div>
  <button>點擊我</button>
</div>

<script>
  document.querySelector('button').addEventListener('click', function() {
    this.innerHTML = '被點擊了!';
  });
</script>

圖片描述

2.5 作為一個內(nèi)聯(lián)的事件處理器

內(nèi)聯(lián)的事件處理器,其 this 指向的是 DOM 節(jié)點自身。

<div>
  <button onclick="console.log(this); console.log(this === document.querySelector('button'))">點擊我</button>
</div>

圖片描述

這個規(guī)則有局限性,只有最外層的 this 符合這個規(guī)則。

<div>
  <button onclick="function test() { console.log(this) }; test();">點擊我</button>
</div>

test 函數(shù)的 this 指向的是全局對象 window。

圖片描述

2.6 其他大部分情況下

排開上述的幾個情況,剩下的函數(shù)大部分情況下在調(diào)用時,this 指向的是全局對象,在瀏覽器中就是 window 對象。

function fn() {
  console.log(this);

  console.log(this === window);
}

fn();

這樣調(diào)用函數(shù),其 this 指向的就是 window 對象了。

有的時候可能會搞混以下情況:

var object = {
  username: '咸魚',
  fn: function() {
    console.log(this.username);

    function thisTest() {
      console.log(this.username);

      console.log(this === window);
    }

    thisTest();
  },
};

object.fn();

圖片描述

這里 thisTest 方法輸出的 username 就會是個 undefined,因為他的 this 指向的是 window,因為他不屬于 object 對象的一個方法,所以 this 就指向了 window。

在回調(diào)函數(shù)中經(jīng)常會碰到這個問題:

var info = {
  account: '123',
  password: '456',
  login: function(cb) {
    setTimeout(function() {
      cb({
        account: this.account,
        password: this.password,
      });
    }, 1000);
  }
};

info.login(function(info) {
  console.log(info);
});

圖片描述

這里回調(diào)函數(shù)獲取的賬號和密碼是 undefined,原因就是 this 的指向問題。

通常會使用保留上層 this 的方式解決這個問題。

var info = {
  account: '123',
  password: '456',
  login: function(cb) {
    var _this = this;

    setTimeout(function() {
      cb({
        account: _this.account,
        password: _this.password,
      });
    }, 1000);
  }
};

info.login(function(info) {
  console.log(info);
});

圖片描述

這樣就能解決這個問題。

另外一個情況也很容易混淆 this :

var object = {
  user: 'no.1',
  say: function() {
    console.log(this.user);
  },
};

var say = object.say;

object.say(); // 輸出:"no.1"
say(); // 輸出:undefined

圖片描述

這是因為把 object 下的 say 方法單獨賦值給 say 變量的時候,其就作為了 window 下的一個方法,所以他的 this 指向的是 window。

在嚴(yán)格模式中,這種情況下的 this 會變成 undefined。

2.7 構(gòu)造函數(shù)

在 JavaScript 構(gòu)造函數(shù)也被成為 對象構(gòu)造器,用于產(chǎn)生對象。

構(gòu)造函數(shù)的聲明和普通函數(shù)幾乎沒有區(qū)別:

function Point(x, y) {
  this.x = x;
  this.y = y;
}

var point = new Point(1, 2);

console.log(point.x); // 輸出:1
console.log(point.y); // 輸出:2

構(gòu)造函數(shù)使用 new 關(guān)鍵字來構(gòu)造對象。所以當(dāng)一個函數(shù)被使用 new 關(guān)鍵字調(diào)用時,這個函數(shù)就會作為一個構(gòu)造函數(shù)。

在一個構(gòu)造函數(shù)被調(diào)用后,其內(nèi)部的 this 會指向一個對象,具體的內(nèi)容可以參考 構(gòu)造函數(shù) 章節(jié)。

3. 修改this

3.1 call 方法和 apply 方法

函數(shù)具有 call 方法和 apply 方法,這兩個方法可以在調(diào)用函數(shù)的時候指定函數(shù)的 this。

var object = {
  user: 'no.1',
};

function say() {
  console.log(this.user);
}

say(); // 輸出:undefined
say.call(object); // 輸出:"no.1"
say.apply(object); // 輸出:"no.1"

圖片描述

通過 callapply 方法將 say 函數(shù)執(zhí)行時候的 this 設(shè)置為 object 對象。

call 方法從第二個參數(shù)開始,表示是要傳遞給當(dāng)前函數(shù)的參數(shù)。

var object = {
  user: 'no.1',
};

function fn(arg1, arg2, arg3) {
  console.log(
    this,
    arg1,
    arg2,
    arg3,
  );
}

fn.call(object, 1, 2, 3);

圖片描述

apply 的第二個參數(shù)是個數(shù)組,數(shù)組里面的項會按數(shù)組的順序作為參數(shù)傳遞給函數(shù)。

var object = {
  user: 'no.1',
};

function fn() {
  console.log(
    this,
    arguments,
  );
}

fn.apply(object, [1, 2, 3]);

圖片描述

通過 arguments 關(guān)鍵字就可以看到當(dāng)前函數(shù)的參數(shù),通常在需要修改 this ,又不確定參數(shù)的情況下,會使用 apply 來修改 this。

3.2 bind

bind 方法用于給一個函數(shù)永久綁定一個指定的 this,bind 不會修改原函數(shù),會返回一個新的函數(shù)。

var obj1 = { value: '今天打磚' };
var obj2 = { value: '明天打轉(zhuǎn)' };

var fn = function() {
  console.log(this);
};

var bindFn1 = fn.bind(obj1)
var bindFn2 = bindFn1.bind(obj2);

bindFn1();
bindFn2();

圖片描述

可以看到 bindFn1 被綁定了 obj1 作為 this,之后不論怎么操作,他的 this 都會是 obj1

bind 還有更多靈活的用法,參數(shù)也可以綁定,有關(guān) bind、call、apply 這三個方法的更詳細(xì)的信息可以查閱對應(yīng)的文檔。

4. 小結(jié)

理解好 this 的處理機(jī)制可以設(shè)計出更加完善的 JavaScript 應(yīng)用程序。

this 在 ES6 的箭頭函數(shù)中的表現(xiàn)也有所不同,可以查閱 ES6 中有關(guān)箭頭函數(shù)的內(nèi)容。