2014-12-21 68 views
11

如果我的代碼如下所示,使用var vs this的首選方法是什麼?javascript var vs

function MyObject() { 
    var self = this; 

    var a = 1; 
    this.b = 2; 

    var innerMethod = function() { 

     logMessage(a); 
     logMessage(self.b); 
    } 
} 

據我瞭解,VAR將只要MyObject的生活生存,所以這個心不是一樣的使用呢?

編輯:

爲了澄清問題多,我從對象內部訪問的變量,而不是從外界只關心。

+0

你可能要檢查:http://stackoverflow.com/questions/3564238/object-oriented-javascript-with-prototypes-vs-closures – phadej

+0

檢查鏈接要理解這一點更清晰HTTPS ://scotch.io/@alZami/understanding-this-in-javascript –

回答

15

var a你不能訪問外然而與this分配範圍可以當你做出一個對象

我們添加屬性this當我們想要的屬性與object.We的生活中確實存在被訪問的變量對局部變量使用var。

「我只希望從對象內部訪問變量,而不是從外部訪問變量」 。

回答這個說法是使用var,如果你想只使用功能外不與VAR定義的變量裏面設置只能由在它們被宣佈,或詞法嵌套範圍範圍代碼。

從而Shomz建議您可以檢查它爲:

var o = new MyObject(); 

一個是不確定的,因爲它是與var

o.a; // undefined 

的定義,同時B將被返回2,因爲它是this

o.b; // 2 
1

如果您想在實例化對象後使用屬性,則爲var將無法​​正常工作,見下圖:

function MyObject() { 
 
    var self = this; 
 

 
    var a = 1; 
 
    this.b = 2; 
 

 
    var innerMethod = function() { 
 

 
     logMessage(a); 
 
     logMessage(self.b); 
 
    } 
 
} 
 

 
var o = new MyObject(); 
 
console.log(o.a); // undefined 
 
console.log(o.b); // 2

+0

我明白這一點,請閱讀我的編輯。 – Toniq

+0

在這種情況下,你可以使用'var'。 – Shomz

5

如果你定義一個變量爲var,那麼它的範圍僅限於功能(無法從外部看到)。在OO方面,它有點像私人財產,實際上根本沒有財產。

如果您將變量定義爲屬性(this.name),則可以從外部訪問它。

功能也一樣。在函數範圍內聲明但未分配給屬性的函數只能從內部看到。如果將屬性分配給屬性,則可以從外部訪問該功能(只要該屬性始終指向該功能)。

function Person(){ 

    // Declared variable, function scope 
    var name = "John";   

    // Property   
    this.surname = "Doe";  

    // Assign anonymous function to property 
    this.getName = function(){ 
     return name; 
    } 

    // Assign anonymous function to property 
    this.getSurname = function(){ 
     return this.surname; 
    } 

    // Declare function 
    function saluteCasually(){  
     console.log("Hi folks!"); 
    } 

    // Declare function 
    function salutePolitely(){   
     console.log("Nice to meet you"); 
    } 

    // Assign (not anonymous) function to property 
    this.salutePolitely = salutePolitely; 

} 

var person = new Person(); 

console.log(person.name);   // undefined 
console.log(person.getName());  // "John" 
console.log(person.surname);  // "Doe" 
console.log(person.getSurname()); // "Doe" 

person.saluteCasually(); // Error: person has not a property "saluteCasually". 
person.salutePolitely(); // Prints "Nice to meet you"; 

person.salutePolitely = function(){ // Properties can be messed with from anywhere! 
    console.log("Bananas"); 
} 
person.salutePolitely(); // Prints "Bananas"; 
+0

你爲什麼要這樣做? this.salutePolitely = salutePolitely;而不是直接this.salutePolitely = function(){ } – Toniq

+0

@Toniq我認爲它至少有三個(也許是主觀的)優勢。 (1)即使屬性的值從外部改變,命名函數也可以從構造函數的範圍訪問。 (2)構造函數中的代碼更清潔一點,因爲你沒有'this'或'self'到處都是。 (3)構造函數中的代碼更清晰,因爲您在視覺上將函數的實現與公有與否相分離。首先你定義所有的功能,然後你只給公共屬性分配屬性,所以你一眼就可以很容易地看到什麼是公共的,什麼不是。 – abl

+0

功能敬禮的範圍會是什麼? – ssal

3

這取決於你想要什麼,使用函數內的VAR不會使它的功能範圍之外的訪問,但是從性能的角度來看,如果你正在使用的對象把一切都在它的內部,你已經存儲這個對象在內存中爲什麼又要定義另一個變量。

內存分析101個形式鉻devtools文檔中說:

內存可以通過一個對象以兩種方式進行:直接通過對象本身,並含蓄地持有其他對象的引用,從而阻止它們被垃圾收集器(簡稱GC)自動處理。

該對象本身擁有的內存大小稱爲淺度大小。典型的JavaScript對象有一些內存保留用於描述和存儲即時值。

通常,只有數組和字符串可以具有明顯的淺層大小。但是,字符串通常將其主存儲在渲染器內存中,只會在JavaScript堆上暴露一個小包裝器對象。儘管如此,即使是一個小對象也可以通過阻止自動垃圾收集進程處理其他對象來間接保存大量內存。當對象本身被刪除時,將釋放的內存大小以及從GC根不可訪問的依賴對象稱爲保留大小。

Devtools Docs

+0

這可能是最好的答案。 – Shomz

+1

那麼使用這個更好的性能呢?我沒有問題,除了代碼看起來相當凌亂與前綴自我。無處不在。 – Toniq

+0

它與在任何地方使用var相同,大部分時間我使用前綴「vars」,所以當我看到var它是一個新的變量,當我看到變量使用這個變量時。所以它取決於你,你可以使它看起來凌亂或看起來不錯。 –