js 愛恨情仇說 this


this 相信大家在寫代碼的時候都會遇到,可是怎么樣才能用好this,估計這個還是有點困難的,雖然你有時候你會用到,但是他所在的具體的幾個場景中所代表的是什么意思了?可能這個你就不是很清楚啊。這個就會在你使用的過程中出現很多的問題,於是今天我們來總結一下this,到底這個this?他真的有想象中的那么難嗎?

其實可以總結為一句話:this指的是調用函數的那個對象

於是我們可以總結出this的四個調用場景:

(1) 方法模式:簡單的說就是使用點表達式或是下標表達式來調用 這里定然是有對象的 這種情況下 this的綁定發生在調用的時候 綁的自然是調它的那個對象了。

於是我們看一下下面這個例子:也是博客園里面我感覺比較經典的一個例子:

var x = 2;
function test() {
    alert(this.x);
}
test();//2
這里text():出來的數據是2 其實我們可以這么理解:
var window.x = 2;
function test() { alert(window.x);// } window.test();//2
 
         
var x = 2; 
function test()
{ this.x = 0; }
test();
alert(x);//0
換一種寫法
var
window.x = 2;
function test()
{ window
.x = 0; }
test();
alert(window.x);
//0

大家能不能明白第一種方式的方法了。

2)函數模式:這個就更簡單了,函數名加調用運算符('()')。不過要小心,這個this綁的可是全局對象,不管你寫哪了。(可以理解成  你不給我指明了   我就自己給它加個全局對象)
當一個函數作為函數調用而不是方法調用時,這個this關鍵字引用全局對象。容易混淆的是,當一個嵌套的函數(作為函數)在一個包含的函數中調用,而這個包含的函數是作為方法調用的,這也是成立的:this關鍵字在包含的函數中有一個值,但是它卻(不太直觀地)引用嵌套的函數體的內部的全局對象。

var a = 'global';
var obj = {
    a : 'local',
    test : function(){
        function test1(){
            alert(this.a);//global 這是為什么呢?其實每個函數在被調用時,其活動對象都會自動獲取兩個特殊的變量:this和arguments。內部函數在搜索這兩個變量時,只會搜索到其活動對象為止,因此永遠不可能直接訪問到外部函數中的這兩個變量了。這個比較蛋疼了怎么辦啊?
        }
        alert(this.a);//local
        test1();
    }
};
obj.test();

下面我們將上面的代碼簡化看一下到底怎么回事啊?
var a = 'global';
var obj = { a : 'local', test : function(){ alert(this.a);//local 其實我們可以這樣寫 alert(obj.a) } }; obj.test(); 能不能理解到了啊

針對上面的問題我們提出如下的結局方案:

var a = 'global';
var obj = {
    a : 'local',
    test : function(){
        var that = this; //this的指向實際是指向它的調用的 這個理解對不對了希望糾正啊?
        function test1(){
            alert(that.a);//local
        }
        test1();
    }
};
obj.test();

3)構造器調用模式  一句話就是用new來調用的  new的時候this就綁定到新對象上了  比較好理解
1.new運算符后面必須跟着一個函數調用。new創建了一個新的沒有任何屬性的對象,然后調用該構造函數,把新的對象作為this關鍵字的值傳遞。
2.構造函數通常沒有返回值。它們初始化作為this的值來傳遞的對象,並且沒有返回值。但一個構造是允許返回一個對象值,並且如果它這么做,返回的對象成為new表達式的值。在此情況下,作為this的值的對象會被拋棄。

var person = function (string){
    this.name = string
}
person.prototype.getName = function (){
    return this.name
}

var myperson = new person('lin');
myperson.getName(); 
如果在一個函數前面帶上一個new來調用,那么將創建一個隱藏到該函數的prototype成員的新對象,同時this將會被綁定到那個新對象上。new前綴也會改變return語句的行為。

可是在構造的原理到底什么樣子的了?看着有點暈啊?

 function newOperator(Constr, args) {
     var thisValue = Object.create(Constr.prototype); // (1)
     var result = Constr.apply(thisValue, args);
     if (typeof result === 'object' && result !== null) {
         return result; // (2)
     }
     return thisValue;
}
參看地方@大額_skylar  佩服。引用一下

4)apply,call調用模式  apply,call是函數對象的方法,你想把誰綁定到this 就直接把它作為第一個參數傳給apply或call就好了。

var a= {n: 'lin'};
var b = function (){
    return this.n;
}
console.log(b.apply(a, null));//輸出lin

希望園友指正。繼續努力加油 。下一個篇閉包了

我打算下面寫一個專們研究這個的今天就不說了。繼續努力。。。。。。希望園友指正


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM