this引用的指向

在javascript的函數(shù)中,除了函數(shù)聲明時定義的形參之外,每個函數(shù)還可以接收另一個隱藏的參數(shù):this,又稱this引用。 這里就講一下this的作用以及不同場景下它的不同指向。this的值(即它的指向)取決于調(diào)用的方式。在javascript中this指向大致有四種情況:

  1. 無任何前綴的函數(shù)調(diào)用時,this指向頂層對象或者全局對象,瀏覽器里是window(nodejs里是global).
function fn(){
  console.log(this);
}
fn();//global{}
  1. 方法調(diào)用的時候,this指向方法所在的對象。
var robot={
  name:"cup",
  say:function(){
    console.log(this.name);
  }
};
robot.say();//cup
  1. 構(gòu)造函數(shù)里,this指向新生成的實例
function Robot(name){
  this.name=name;
  this.say=function(){
    console.log(this.name);
  }
};
robot_1=new Robot('bower');
robot_1.say();//bower
robot_2=new Robot('cup');
robot_2.say();//cup
  1. apply/call調(diào)用的時候,this指向apply/call方法中的第一個參數(shù)。
var robot_1={name:'cup'};
var robot_2={name:'bower'};
function say(){
  console.log(this.name);
}
say.apply(robot_1);//cup
say.call(robot_2);//bower

在最外層代碼中,this引用引用的是全局對象. 在函數(shù)內(nèi),this引用根據(jù)函數(shù)調(diào)用的方式不同而有不同的含義.
通過類和對象這課程的學(xué)習(xí)我們知道,方法是對象的屬性所引用的函數(shù).下面是一個關(guān)于關(guān)于方法和this引用的具體例子解析.
1.方法內(nèi)的this調(diào)用

//對象定義
var robot = {
    name : "cup",
    say : function() { console.log( "Hi, I'm " + this.name + "."); }
}
robot.say()            // 打印結(jié)果為 Hi, I'm cup.
//對象robot是被調(diào)用的對象,say是方法。

首先是將對象賦給了變量robot。這個對象有兩個屬性。屬性name的值為"cup",屬性say的值是一個函數(shù)。該函數(shù)稱作say方法。 被調(diào)用的方法say內(nèi)的關(guān)鍵字this引用指向了被調(diào)用的對象robot。
2.函數(shù)內(nèi)的this調(diào)用

var robot = {
    name : "cup",
    say : function() { console.log( "Hi, I'm " + this.name + "."); }
}
var fn = robot.say;
// 將robot.say引用的函數(shù)賦值給全局變量 fn.

fn()                        // 打印結(jié)果為 Hi, I'm .
// 執(zhí)行函數(shù)(全局的方法),this引用了全局對象,由于全局對象沒有name屬性,所以沒有取到值.

根據(jù)我們之前講的,現(xiàn)在這個函數(shù)由于是無任何前綴的直接調(diào)用的,this應(yīng)該是指向了全局對象,我們確認(rèn)一下this是否指向了全局對象

var robot = {
    name : "cup",
    say : function() { console.log( "Hi, I'm " + this.name + "."); }
}
var fn = robot.say;
//將robot.say引用的函數(shù)賦值給全局變量 fn.
//相當(dāng)于給全局對象定義了一個屬性fn,并賦予robot.say所指代的函數(shù).

var name = "bower",
//相當(dāng)于給全局對象定義了一個屬性name,賦值為"bower",在瀏覽器里,上面這行代碼等價于 window.name = "bower";

fn()                    // 打印結(jié)果為 Hi, I'm bower.
//執(zhí)行函數(shù)fn(相當(dāng)于調(diào)用全局對象的fn方法),執(zhí)行時this引用了全局對象.所以this.name的值是"bower".

函數(shù)的apply與call方法

所有的函數(shù)都默認(rèn)包含apply和call兩種方法,調(diào)用函數(shù)的apply或call方法,就相當(dāng)于調(diào)用該函數(shù).不考慮函數(shù)內(nèi)的this引用的話,這和類似于 say() 這樣的普通調(diào)用方式是一樣的。 而apply和call的功能是,通過傳參的方式,強制函數(shù)內(nèi)的this指定某一對象。this引用的會被指向apply/call的第一個參數(shù)。
下面是一個使用了apply方法和call方法的函數(shù)調(diào)用的例子。

function say(){ console.log(this.name); }
var robot = {name:"cup"};

say.apply(robot)            // 打印結(jié)果為cup
//通過apply調(diào)用函數(shù)say。函數(shù)內(nèi)的this引用引用了對象robot。

say.call(robot)            // 打印結(jié)果為cup
//通過call調(diào)用函數(shù)say。函數(shù)內(nèi)的this引用引用了對象robot。

下面是一個使用了apply方法和call方法的對某對象的方法進(jìn)行調(diào)用的例子。

var robot_1 ={
  name:"cup",
  say:function(){
          console.log(this.name)
          }
};
var robot_2 ={ name:"bower" };

robot_1.say() //打印結(jié)果為cup

robot_1.say.apply(robot_2)            // 打印結(jié)果為bower
//通過apply調(diào)用robot_1.say方法。方法內(nèi)的this引用引用了robot_2

robot_1.say.call(robot_2)                // 打印結(jié)果為bower
//通過call調(diào)用robot_1.say方法。方法內(nèi)的this引用引用了robot_2

apply與call之間的不同之處在于兩者對其他參數(shù)的傳遞方式。
對于apply來說,剩余的參數(shù)將通過數(shù)組來傳遞,而call是直接按參數(shù)列表傳遞。

function say(age, gender){console.log("My name is " + this.name + ",I'm a " + age + " years old " + gender + ".")}

say.apply({name:"cup"}, [12, "boy"])            //打印結(jié)果為 My name is cup,I'm a 12 years old boy.
// this.name = "cup", age = 12, gender = "boy"  作為第二個參數(shù)的數(shù)組中的元素都是函數(shù)say的參數(shù),按順序依次對應(yīng)

say.call({name:"cup"}, 12, "boy")                //打印結(jié)果為 My name is cup,I'm a 12 years old boy.
// this.name = "cup", age = 12, gender = "boy"  從第二個參數(shù)起的參數(shù)都是函數(shù)say的參數(shù),按順序依次對應(yīng)

事例:

function Tool(name, usage){
    this.name = name;
    this.usage = usage;
    this.get_info = function() {console.log("This is " + this.name + ", the usage of it is " + this.usage + ".")}
}
var cycling = new Tool("cycling","transport");

function display(date){
    console.log(this.name+","+this.usage+","+date)
}

display.apply(cycling,["1970"]);
//cycling,transport,1970

自定義類

一個典型的定義類的方法

function Car(x,y){ 
  this.x = x;
  this.y = y;
  this.run = function(x_increase, y_increase){
      this.x += x_increase;
      this.y += y_increase;
  }
  this.show = function(){
      console.log("( " + this.x + "," + this.y + " )");
  }
}

通過上述代碼,我們就擁有了一個名為Car的“類”。它有兩個成員變量x和y還有一個成員函數(shù)run。那么我們就可以像用Object一樣使用它:

var a_car = new Car(2,4); //獲得了一個坐標(biāo)為(2,4)的Car對象,x為2,y為9
a_car.run(10,5);          //a_car.x變成了12,a_car.y變成了9
a_car.show();             //打印結(jié)果
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

  • 在javascript的函數(shù)中,除了函數(shù)聲明時定義的形參之外,每個函數(shù)還可以接收另一個隱藏的參數(shù):this,又稱t...
    耦耦閱讀 391評論 0 1
  • 函數(shù)和對象 1、函數(shù) 1.1 函數(shù)概述 函數(shù)對于任何一門語言來說都是核心的概念。通過函數(shù)可以封裝任意多條語句,而且...
    道無虛閱讀 4,961評論 0 5
  • 1.概念 在JavaScript中,this 是指當(dāng)前函數(shù)中正在執(zhí)行的上下文環(huán)境,因為這門語言擁有四種不同的函數(shù)調(diào)...
    BluesCurry閱讀 1,241評論 0 2
  • 1.ios高性能編程 (1).內(nèi)層 最小的內(nèi)層平均值和峰值(2).耗電量 高效的算法和數(shù)據(jù)結(jié)構(gòu)(3).初始化時...
    歐辰_OSR閱讀 30,265評論 8 265
  • 參加“21天小白理財訓(xùn)練營”算是我人生中比較有意義的事件之一,在訓(xùn)練營即將結(jié)束之際,我想,我需要寫點什么來給自己做...
    水澹生煙閱讀 590評論 1 8

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