2010-04-25 101 views
6

聲明一個變量與thisvar有什麼區別?用這個或var聲明變量?

var foo = 'bar' 

this.foo = 'bar' 

當你用thisvar

編輯:有一個簡單的問題作出決定時,我可以問我自己,如果我想使用varthis

+0

對於構造,看看[這個問題](http://stackoverflow.com/q/13418669/1048572) – Bergi 2015-01-22 02:34:55

回答

13

如果它是global code(該代碼不是任何函數的一部分),那麼您將在具有兩個片段的全局對象上創建一個屬性,因爲thisglobal code指向全局對象。

在這種情況下,不同的是,使用var語句時,該屬性不能被刪除,例如:

var foo = 'bar'; 
delete foo; // false 
typeof foo; // "string" 

this.bar = 'baz'; 
delete bar; // true 
typeof bar; "undefined" 

注:以上片段將表現不同的Firebug控制檯的,因爲它運行與EVAL,並在評估和演示代碼執行上下文中執行的代碼的代碼允許與var創建標識符的刪除,嘗試here

如果代碼是你應該知道,this關鍵字無關的功能範圍功能的一部分,是設置隱式,這取決於一個函數是如何被調用的保留字,例如:

- 當一個函數被調用作爲方法(函數調用時作爲對象的成員):

obj.method(); // 'this' inside method will refer to obj 

- 甲正常的函數調用:

myFunction(); // 'this' inside the function will refer to the Global object 
// or 
(function() {})(); 

- 當新的運算符用於:

var obj = new Constructor(); // 'this' will refer to a newly created object.  

你甚至可以設置this值明確,使用callapply方法,例如:

function test() { 
    alert(this); 
} 
test.call("hello!"); //alerts hello! 

您還應該知道JavaScript只有函數範圍,並且使用聲明的變量語句只能在相同的函數或下面定義的任何內部函數內訪問。

編輯:尋找你發佈到@David's answer的代碼,讓我評論:

var test1 = 'test'; // two globals, with the difference I talk 
this.test2 = 'test'; // about in the beginning of this answer 

//... 

function test4(){ 
    var test5 = 'test in function with var'; // <-- test5 is locally scoped!!! 
    this.test6 = 'test in function with this'; // global property, see below 
} 

test4(); // <--- test4 will be called with `this` pointing to the global object 
     // see #2 above, a call to an identifier that is not an property of an 
     // object causes it 

alert(typeof test5); // "undefined" since it's a local variable of `test4` 
alert(test6); // "test in function with this" 

您不能訪問功能外test5變量,因爲是局部範圍,且只存在withing的該功能的範圍。

編輯:在回答您的評論

聲明變量我建議你總是使用var,這究竟是什麼做。

this值的概念將在您開始使用constructor functions對象和方法時變得有用。

+0

thx很多非常明確的答案 – meo 2010-04-25 21:07:40

+0

不客氣@meo,如果有什麼不明確的,不要猶豫,評論。 – CMS 2010-04-25 21:09:48

+0

有沒有一個簡單的問題,我可以問自己,當決定是否我想使用'var'或'this'? – meo 2010-04-25 21:15:16

5

如果使用var,變量的作用域是當前功能。

如果使用this,那麼你的值上任何this是(其是該方法被稱爲上或(如果new關鍵字已經被使用)被創建的對象的對象的屬性分配。

+0

因此如何談到,我不能訪問var test5,但我可以在以下示例中測試6:http://jsfiddle.net/Ew3pD/? – meo 2010-04-25 20:47:08

+1

@meo因爲測試5失去了它的範圍,一旦測試4功能留下。當你調用this.test6時,你正在全局範圍上創建一個變量,因爲函數沒有在對象上被調用。 – 2010-04-25 20:52:12

+1

@meo:當一個沒有上下文對象的函數被調用時,test6被分配給'this'這個全局對象被假定。在全局對象上創建的屬性是全局級別創建的變量的同義詞(但完全相同)。您不能在全局級別上爲全局對象創建屬性,因爲它們都是針對全局對象的。 – AnthonyWJones 2010-04-25 20:56:49

3
var foo = 'bar' 

這將範圍foo變量函數包裝,或全局範圍。

this.foo = 'bar' 

這將範圍foo變量的this對象,它完全像這樣:

window.foo = 'bar'; 

someObj.foo = 'bar'; 

你問題的第二部分似乎是什麼this對象,並且這是由函數的運行環境決定的。You can change what this is by using the apply method that all functions have。您也可以高於全球對象this變量的缺省的對象之外,通過:

someObj.foo = function(){ 
    // 'this' is 'someObj' 
}; 

function someObj(x){ 
    this.x=x; 
} 
someObj.prototype.getX = function(){ 
    return this.x; 
} 
var myX = (new someObj(1)).getX(); // myX == 1 
3

您使用var當你要定義一個簡單的局部變量,你會在一個典型的功能: -

function doAdd(a, b) 
{ 
    var c = a + b; 
    return c; 
} 

var result = doAdd(a, b); 

alert(result); 

然而this有當call上一本功能使用的特殊含義離子。

function doAdd(a, b) 
{ 
    this.c = a + b; 
} 

var o = new Object(); 
doAdd.call(o, a, b); 
alert(o.c); 

您在使用call上的doAdd是之前創建的對象注意第一個參數。在內部執行doAdd this將引用該對象。因此它會在該對象上創建一個c屬性。

通常雖然功能被分配給這樣的對象的屬性: -

function doAdd(a, b) 
{ 
    this.c = a + b; 
} 

var o = new Object(); 
o.doAdd = doAdd; 

現在函數可以執行使用。註釋: -

o.doAdd(a, b);  
alert(o.c); 

有效o.doAdd(a, b)o.doAdd.call(o, a, b)

1

在構造函數中,你可以使用VAR來模擬私有成員,這模擬公共成員:

function Obj() { 
    this.pub = 'public'; 
    var priv = 'private'; 
} 

var o = new Obj(); 
o.pub; // 'public' 
o.priv; // error 
+0

實際上'o.priv;'不會產生錯誤,它只會返回'undefined' :) – CMS 2010-04-26 01:37:04

1

舉例這個var如下解釋:


function Car() { 
    this.speed = 0; 

    var speedUp = function() { 
     var speed = 10; // default 
     this.speed = this.speed + speed; // see how this and var are used 
    }; 

    speedUp(); 
} 


+0

請注意,'speedUp'函數的'this'值將始終是全局對象,因爲它的調用方式爲no * object context *('speedUp();'),除非'Car'函數在沒有'new'運算符的情況下被調用,它與外部this.speed無關。在這種情況下,外部函數中的'this'也將引用全局對象,泄漏'speed'全局變量('window.speed')。 – CMS 2010-04-26 01:34:39

1
var foo = 'bar'; // 'var can be only used inside a function 

this.foo = 'bar' // 'this' can be used globally inside an object