2012-09-11 48 views
1

我想弄清楚如何在創建它後向方法添加方法。
在我的代碼中,我不能使用Person的prototype屬性來添加一個新的公共方法,該方法可以訪問Person的變量。 (附加在原型屬性上的函數不能關閉主函數中的變量)。
與第一種方式不同,第二種方式起作用 - 人2看起來像被稱爲特權方法 - http://www.crockford.com/javascript/private.html函數附加到原型屬性沒有關閉

function Person(name, age){} 
Person.prototype.details = function(){ 
    return "name: "+name+", age: "+age; 
}; 

function Person2(name, age){ 
this.details = function(){ 
    return "name: "+name+", age: "+age;}; 
} 

var per1 = new Person("jim", 22); 
var per2 = new Person2("jack", 28); 

per1.details(); 
//=> ReferenceError: age is not defined 
per2.details(); 
//=> "name: jack, age: 28" 

回答

0

當然不是,該功能是在一個聲明範圍,與參數/變量被聲明的範圍不同,所以JS不知道你正在使用哪些變量。假設你有第二次關閉,或者更好(實際上,實際上更糟糕):一個叫做name的全局變量。 JS會選擇哪一個?

下面是一個例子給你:

function MyObject(name) 
{ 
    var localVar = 'foobar'; 
    this.evilMethod = (function(localVar) 
    { 
     return function() 
     { 
      console.log('localVar = '+localVar);//=== name 
     }; 
    })(name); 
    this.badMethod = function() 
    { 
     console.log('localVar = '+ localVar);// === 'foobar' 
    }; 
} 
var name = 'Global Name'; 
var anotherClosure = (function(name) 
{ 
    var localVar = name.toLowerCase(); 
    return function() 
    { 
     console.log(name); 
     console.log(localVar); 
    } 
})('Bobby'); 
MyObject.prototype.closureVars = function() 
{ 
    console.log(name);//Global name 
    console.log(localVar);//undefined 
}; 

現在第一關:這是可怕的代碼,但你明白了一點:你可以有數百個變量具有相同的名稱,其中一個JS有權使用,可能並不總是很清楚。

賦予原型對實例閉包變量的訪問也有其他含義:例如,您可以更改它們的值,這首先破壞了閉包的關鍵點。
但國泰里程最大的問題會是:多個實例!如果你創建了一個構造函數,那麼你將會用它來實例化多個對象。 如果它們都共享相同的原型,那麼這將如何工作?

只需指定要在原型來訪問屬性的參數/變量,如FishBasketGordo的例子並

+0

yikes,我明白了,謝謝 – deepak

+0

對不起,我剛剛下班回家,有點打架:) –

4

不,他們沒有關閉構造函數的變量。他們處於不同的範圍。

// This function is in one scope. 
function Person(name, age) { 
} 

// This statement is in the parent scope, which 
// doesn't have access to child scopes. 
Person.prototype.details = function(){ 
    return "name: "+name+", age: "+age; 
}; 

這是「公共」的功能在JavaScript中的工作方式。您可以通過在構造函數中定義它使details特權功能:

function Person(name, age) { 
    this.details = function() { 
     return "name: "+name+", age: "+age; 
    }; 
} 

當然,這意味着Person每個實例得到它的details功能的自己的副本。

您也可以作爲@Chuck建議,使nameage公共成員,在其中你將有一個原型函數訪問它們:

function Person(name, age) { 
    this.name = name; 
    this.age = age; 
} 

Person.prototype.details = function(){ 
    return "name: " + this.name + ", age: " + this.age; 
}; 
+3

你也可以在構造函數中分配'this.name'和'this.age'。 – Chuck

+0

@Chuck:我不想這樣做,我想要名稱和年齡是私人的(實質上創建一個不可變的Person對象) – deepak

+0

如果這是@deepak的情況,那麼您應該使用特權方法。 – FishBasketGordo

1

號通常你要麼使用第二種方法,或在構造函數中設置this._name = name;和引用它這種方式在另一種方法中。