2016-05-13 160 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'不在全局范围内。) –

相关问题