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

全部開(kāi)發(fā)者教程

JavaScript 入門(mén)教程

JavaScript this

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

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

1. 全局下的 this

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

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

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

圖片描述

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

2. 函數(shù)中的 this

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

2.1 對(duì)象下的方法

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

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

person.say();

圖片描述

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

2.2 原型鏈上方法的 this

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

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)建一個(gè)對(duì)象。

所以 object 的第一原型就是 __proto__ 對(duì)象。

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

2.3 getter / setter 下的 this

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

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ì)上也可以理解成兩個(gè)函數(shù),作為對(duì)象下的函數(shù),在調(diào)用的時(shí)候 this 也會(huì)指向該對(duì)象。

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

作為 DOM 節(jié)點(diǎn)的事件處理器的時(shí),函數(shù)的 this 會(huì)指向這個(gè) DOM 對(duì)象。

<div>
  <button>點(diǎn)擊我</button>
</div>

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

圖片描述

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

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

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

圖片描述

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

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

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

圖片描述

2.6 其他大部分情況下

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

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

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

fn();

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

有的時(shí)候可能會(huì)搞混以下情況:

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

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

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

    thisTest();
  },
};

object.fn();

圖片描述

這里 thisTest 方法輸出的 username 就會(huì)是個(gè) undefined,因?yàn)樗?this 指向的是 window,因?yàn)樗粚儆?object 對(duì)象的一個(gè)方法,所以 this 就指向了 window。

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

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ù)獲取的賬號(hào)和密碼是 undefined,原因就是 this 的指向問(wèn)題。

通常會(huì)使用保留上層 this 的方式解決這個(gè)問(wèn)題。

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);
});

圖片描述

這樣就能解決這個(gè)問(wèn)題。

另外一個(gè)情況也很容易混淆 this :

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

var say = object.say;

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

圖片描述

這是因?yàn)榘?object 下的 say 方法單獨(dú)賦值給 say 變量的時(shí)候,其就作為了 window 下的一個(gè)方法,所以他的 this 指向的是 window。

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

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

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

構(gòu)造函數(shù)的聲明和普通函數(shù)幾乎沒(méi)有區(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)鍵字來(lái)構(gòu)造對(duì)象。所以當(dāng)一個(gè)函數(shù)被使用 new 關(guān)鍵字調(diào)用時(shí),這個(gè)函數(shù)就會(huì)作為一個(gè)構(gòu)造函數(shù)。

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

3. 修改this

3.1 call 方法和 apply 方法

函數(shù)具有 call 方法和 apply 方法,這兩個(gè)方法可以在調(diào)用函數(shù)的時(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"

圖片描述

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

call 方法從第二個(gè)參數(shù)開(kāi)始,表示是要傳遞給當(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 的第二個(gè)參數(shù)是個(gè)數(shù)組,數(shù)組里面的項(xiàng)會(huì)按數(shù)組的順序作為參數(shù)傳遞給函數(shù)。

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

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

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

圖片描述

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

3.2 bind

bind 方法用于給一個(gè)函數(shù)永久綁定一個(gè)指定的 this,bind 不會(huì)修改原函數(shù),會(huì)返回一個(gè)新的函數(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 都會(huì)是 obj1。

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

4. 小結(jié)

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

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