2016-11-20 45 views
1

有沒有辦法獲得用構造函數創建的變量的名稱?在javascript中獲取構造函數的名稱

var TestFunction = function() { 
    this.name = ???(); // should return '$testName' 
} 
var $testName = new TestFunction(); 

$testName.name應該返回$testName THX

+3

聽起來像X/Y問題。爲什麼你認爲你想讓函數能夠找出這樣的變量名?你的*實際*最終目標是什麼? –

+0

這是一個cookie系統,所以你可以說test = new Cookie('value',10000);如果test.name是test – howtoweb

+0

恐怕你不得不重複它作爲一個參數。 –

回答

6

應該返回 '$測試名'

這意味着你問一個函數如何知道變量及其結果的名稱(或者更確切地說,調用它的結果是new)即將被分配給。這不可能,沒有的並非最不重要的,因爲這些可能機制爲,:

a = b = c = d = new TestFunction(); 
// or 
new TestFunction(); 
// or 
foo(new TestFunction()); 

...但真的是因爲從根本上,函數沒有企業瞭解有關上下文任何在它被稱爲比其他程序員選擇通過傳遞參數來告訴它。

因此,如果你想要的功能有這些信息,你需要在通過它,即使這是重複的:

var $testName = new TestFunction("$testName"); 

有一個特殊的情況下(在全局範圍變量)在那裏你可以避免重複這個名字,只有把它作爲參數傳遞給函數(離開var $testname =部分),然後讓函數創建「變量」,但它會將函數綁定到全局範圍,深入Bad Idea™領域。 :-)

這是特殊情況的樣子。 強烈建議不要這樣做。(相反:squint有一個excellent suggestion in a comment

// STRONGLY RECOMMEND NOT DOING THIS 
function TestFunction(name) { 
    window[name] = this; // Creates a global 
    this.name =name; 
} 

new TestFunction("$testname"); 
console.log($testname); // {name: "$testname"} 

這工作,因爲當你創建全局對象(你可以通過瀏覽器訪問window)上的屬性,它會創建一個全局變量。

請不要這樣做。 :-)


關於squint's Proxy idea,它會是這個樣子:

// Requires ES2016 ("ES6") support in the browser 
 
// Proxy cannot be shimmed, so transpiling won't help 
 
const cookieStore = new Map(); // Our fake storage; you'd use the browser's actual cookie store 
 
function cmAccessor(name, ...args) { 
 
    if (args.length == 0) { 
 
    // Getter; you'd actually use the browser store 
 
    const entry = cookieStore.get(name); 
 
    return entry && entry.value; 
 
    } 
 
    // Setter 
 
    const [value, duration] = args; 
 
    console.log(`Setting '${name}' to '${value}' for ${duration}`); 
 
    // You'd use the real browser store here 
 
    cookieStore.set(name, {value, duration}); 
 
} 
 
const CM = new Proxy(Object.create(null), { 
 
    get(target, name) { 
 
    let result = target[name]; 
 
    if (!result) { 
 
     result = cmAccessor.bind(null, name); 
 
     target[name] = result; 
 
    } 
 
    return result; 
 
    } 
 
}); 
 
CM.cookie1("cookie1 value", 42); 
 
CM.cookie2("cookie2 value", 42); 
 
console.log(CM.cookie1()); 
 
console.log(CM.cookie2());

但你可能會更好只使用一個功能,網HRS歐洲的jQuery :

// This version is ES5 compatible 
 

 
const cookieStore = new Map(); // Our fake storage; you'd use the browser's actual cookie store 
 

 
function CM(name, value, duration) { 
 
    switch (arguments.length) { 
 
    case 0: 
 
     throw new Error("'name' is required"); 
 
    case 1: 
 
     // Getter 
 
     // You'd use the browser's real cookie store here 
 
     const entry = cookieStore.get(name); 
 
     return entry && entry.value; 
 
    default: 
 
     // Setter 
 
     console.log("Setting '" + name + "' to '" + value + "' for " + duration); 
 
     // You'd use the real cookie store here 
 
     cookieStore.set(name, {name: name, value: value}); 
 
    } 
 
} 
 

 
// Usage: 
 
CM("cookie1", "cookie1 value", 42); 
 
CM("cookie2", "cookie2 value", 42); 
 
console.log(CM("cookie1")); 
 
console.log(CM("cookie2"));

相關問題