javascript this詳細介紹

ii_chengzi發表於2019-06-09

this的值是在執行時確定的

  JS中的this究竟代表什麼,這是在程式執行時根據上下文環境確定,可以分為以下幾種情況。

  1. 全域性作用域中的this

  在全域性作用域中,this指向window物件。

  ?

  1

  2

  3

  4

  5

  6

  console.log(this);//指向window物件

  this.x = 5//在全域性作用域內建立一個x

  //與this.x = 5的等價情況:

  //var x = 5;

  //x = 5;

  在全域性作用域中執行var x=5,其實是為window物件建立一個屬性x,並令其等於5。

  若定義變數時不加var,JS會認為該變數為全域性變數,會將其當作window物件的屬性。

  2. 函式中的this

  JS中函式有兩種,直接呼叫的函式稱為普通函式,透過new建立物件的函式稱為建構函式。

  2.1 建構函式中的this

  建構函式的this指向它所建立的物件,如:

  ?

  1

  2

  3

  4

  function Person(name){

  this.name = name;//this指向該函式建立的物件person

  }

  var person = new Person("chaimm");

  2.2 普通函式中的this

  普通函式的this指向window物件。

  若上述例子,直接執行Perosn函式,則其中this代表window物件,因此該函式執行後會建立一個全域性的name。

  ?

  1

  2

  3

  4

  function Person(name){

  this.name = name;//this指向window

  }

  Person("chai");//當作普通函式執行,this指向window物件

  3. 物件中的this

  物件中的this指向當前物件,如:

  ?

  1

  2

  3

  4

  5

  6

  var person = {

  name : "chaimm",

  getName : function(){

    this.name;

  }

  }

  上述程式碼中this指向函式getName所屬的物件。

  但是,如果一個物件的函式中又巢狀了一個函式,這個函式的this指向的卻是window,而並不是其外層的物件。

  ?

  1

  2

  3

  4

  5

  6

  7

  8

  var person = {

  name : "chaimm",

  setName : function(name){

  (function(name){

  this.name = name; //此時this並不代表person物件,而是代表window物件

  })(name);

  }

  }

  上述示例中,person物件中有一個getName函式,而getName函式內部又有一個函式,這個函式內部的this指向window物件,而非person物件,這是JS的一個bug!一般作如下處理,規避這個bug:

  ?

  1

  2

  3

  4

  5

  6

  7

  8

  9

  var person = {

  name : "chaimm",

  setName : function(name){

  var thar = this;//將this賦給that

  (function(name){

  that.name = name;//此時that指向person物件

  })(name);

  }

  }

  我們在person物件的第一層函式中,將this賦給區域性變數that,然後在第二層函式中使用that,此時that指向person物件,可對person的屬性進行操作。

  注意:若將一個物件中的函式賦給一個變數後,再透過該變數呼叫這個函式,此時該函式中的this指向window,而非該物件,如下所示:

  ?

  1

  2

  3

  4

  5

  6

  7

  8

  9

  10

  11

  var person = {

  name : "chaimm",

  getName : function(){

  return this.name;

  }

  }

  //將getName函式賦給一個新的變數

  var newGetName = person.getName;

  //透過新的變數呼叫這個函式,這個函式中的this將指向window

  newGetName();//若全域性作用域中沒有name,則將返回undefined

  4. 用 和apply函式給this開掛

  這兩個函式都能手動指定被呼叫函式內部的this指向哪個物件。

  ?

  1

  2

  3

  4

  5

  6

  7

  8

  9

  10

  11

  12

  13

  14

  //定義一個建構函式

  var Person = function(name){

  this.name = "";

  this.setName = function(name){

  this.name = name;

  }

  }

  //建立兩個物件

  var personA = new Person("A");

  var personB = new Person("B");

  //使用personA的setName函式去修改personB的name屬性

  personA.setName.apply(personB,["C"];

  apply用法

  物件A.函式名。apply(物件B, 引數列表);

  當物件B作為apply的第一個引數傳給apply時,物件A的函式中this就指向了物件B,此時物件A的該函式對this的操作將會作用在物件B上,由此實現了用物件A去呼叫物件B的函式。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31543790/viewspace-2647136/,如需轉載,請註明出處,否則將追究法律責任。

相關文章