2016-05-13 202 views
2

我想創建一個函數來創建一個函數來不斷返回一個對象的鍵,但我不確定如何編寫它。如何創建一個函數來創建一個函數來不斷返回一個對象的鍵

例如,我可以做如下:

var parent = {data: 123} 
var child = {} 

child.data = function() { 
    return parent.data 
} 

child.data() // 123 
parent = {data: 456} 
child.data() // 456 

這工作得很好,但我想創建一個用於創建數據的功能,如一些功能:

var parent = {data: 123} 
var child = {} 
create_data_function(parent, child, "data") 

child.data() // 123 
parent = {data: 456} 
child.data() // 456 

下將不起作用,因爲「from」變量被重新分配了

function create_data_function(from, to, key) { 
    to[key] = function() { 
     return from[key] 
    } 
} 

正在創建create_data_functio有可能嗎? 我不確定搜索什麼來尋找解決方案。

感謝您的閱讀:)

+0

I a @ T.J.Crowder。該代碼適用於我:https://jsfiddle.net/ye7onjyu/ – sheeldotme

+0

嗨@ T.J.Crowder,謝謝你試用它,我應該創建了一個jsfiddle,對此感到抱歉。 – John

+1

我意識到原來的例子有一個錯字,我想要做的是parent = {data:456},而不是parent.data = 456,我已經爲你的小提琴派上了用場了,現在https://jsfiddle.net/hf664p15/ – John

回答

0

讓我們指的是最初的對象parent點爲對象1,並將新對象分配給parent爲對象2.

parent變量的值是一個對象引用,最初是一個參考對象物1時這樣做:

create_data_function(parent, child, "data"); 

值的parent是REA d並傳入create_data_function。該值是對象1的參考。根本不涉及parent變量傳遞到create_data_function。它創建的功能將關閉在從create_data_function調用創建它,這將始終包含一個參考from參數對象1.

要創建一個函數,它你的描述,該功能必須有訪問parent變量本身。 JavaScript沒有任何形式的傳遞參考(它允許你將一個變量的引用傳遞給一個函數),所以我們必須找到另一種方式來給create_data_function訪問parent變量。

最簡單的方法是確保create_data_function關閉了parent,通過在訪問parent一個範圍界定它,就像這樣:

var parent = {data: 123}; 
 
var child = {}; 
 
create_data_function(child, "data"); 
 
//     ^---- Note we aren't passing in `parent` 
 

 
snippet.log(child.data()); // 123 
 
parent = {data: 456}; 
 
snippet.log(child.data()); // 456 
 

 
function create_data_function(to, key) { 
 
// Note no `from` ------------^ 
 
    to[key] = function() { 
 
     return parent[key]; 
 
//    ^^^^^^------ instead we use `parent` directly 
 
    }; 
 
};
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --> 
 
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

這是可能的,因爲create_data_function在可以直接使用parent變量的地方創建。

但是如果不是?我們希望通過傳遞一個存取功能解決它爲create_data_function,像這樣:

// Note that because `parent` is a local within `test`, 
 
// and `create_data_function` isn't, `create_data_function` 
 
// doesn't have direct access to `parent` (it doesn't *close over* 
 
// `parent`). 
 
function test() { 
 
    var parent = {data: 123}; 
 
    var child = {}; 
 
    create_data_function(function() { // So we give it a function to call 
 
    return parent;     // to get `parent`'s current value 
 
    }, child, "data"); 
 

 
    snippet.log(child.data()); // 123 
 
    parent = {data: 456}; 
 
    snippet.log(child.data()); // 456 
 
} 
 

 
function create_data_function(fromAccessor, to, key) { 
 
// Accept the accessor -------^ 
 
    to[key] = function() { 
 
     return fromAccessor()[key]; 
 
// Call it ----^^^^^^^^^^^^^^ 
 
    }; 
 
}; 
 

 
test();
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --> 
 
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

這與ES2015語法有點不太笨重,因爲新箭頭功能:

// THIS EXAMPLE REQUIRES ES2015 SUPPORT IN YOUR BROWSER 
 

 
function test() { 
 
    var parent = {data: 123}; 
 
    var child = {}; 
 
    create_data_function(() => parent, child, "data"); 
 
    // The accessor func ^^^^^^^^^^^^ 
 

 
    snippet.log(child.data()); // 123 
 
    parent = {data: 456}; 
 
    snippet.log(child.data()); // 456 
 
} 
 

 
function create_data_function(fromAccessor, to, key) { 
 
    to[key] = function() { 
 
     return fromAccessor()[key]; 
 
    }; 
 
}; 
 

 
test();
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --> 
 
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

+0

感謝您的答案,是的,有點笨重的JavaScript,但似乎沒有辦法解決這個問題,一個好主意,將函數包裝在一個函數 – John

+0

只是好奇,你認爲傳遞上下文參數如https: //jsfiddle.net/L7stc9rd/?它正在修改當然問題中的原始函數參數,但除此之外,我認爲它會工作正常嗎?雖然它遇到了jsfiddle – John

+0

上的問題@John:只有當'parent'是一個對象的屬性時才起作用。這將是如果'var parent'在全局範圍,但通常你想避免全局性,所以...(你的小提琴不工作,因爲jsFiddle的驚人的默認包裝你的代碼'window.onload = function() {/ * ..你的代碼在這裏...... * /};',所以你的'var parent'不在全局範圍內。) –

相關問題