有没有办法在函数中重新分配参数,并让它也影响调用范围

Is there a way to reassign an argument within a function, and have it also affect the calling scope?

本文关键字:参数 范围 调用 影响 分配 函数 新分配 有没有      更新时间:2023-09-26

我正在尝试做的是为Javascript对象构建一个clone()函数。如您所知,Javascript中缺乏本机功能可能会很痛苦。我有一个很好的方法来做到这一点,但可用性方面,它很尴尬。这是到目前为止的功能:

function clone(objectToClone) {
    var myClone = function() {};
    myClone.prototype = objectToClone;
    return [
        new myClone(),
        new myClone()
    ];
}

如您所见,目前我只返回一个包含两个克隆的数组。这使得用法看起来像这样:

// usage
var bar = new foo();
bar = clone(bar); // forks bar into two separate copies of bar (awkward)
// bar[0] is now clone 1
// bar[1] is now clone 2

我想做的是能够做如下事情:

function clone(objectToClone) {
    var myClone = function() {};
    myClone.prototype = objectToClone;
    objectToClone = new myClone(); // somehow magically?
    return new myClone();
}
// usage
var bar = new foo();
var baz = clone(bar); // returns a copy, and bar is now one of the copies as well.
// bar is now clone 1
// baz is now clone 2

不幸的是,这不起作用,因为分配参数不会影响调用范围。我希望有人能够帮助想出一些js技巧,让我能够在所需的庄园中使用该功能。任何想法都非常感谢。

若要获得所需的结果,需要传入具有属性的对象,然后修改这些属性。 这是在javascript中获取引用的最佳方式,它允许您更改原始引用。 当原始参数只是作为普通函数参数传递时,您无法更改它。 Javascript没有这些类型的引用。

function clone(holder) {
    var myClone = function() {};
    myClone.prototype = holder.input;
    holder.input = new myClone(); // somehow magically?
    return new myClone();
}
// usage
var holder = {};
var holder.input = new foo();
var holder.output = clone(holder); // returns a copy, and holder.input is now a copy too
// holder.input is now clone 1
// holder.putput is now clone 2

您可以让克隆函数返回副本,同时保留原始副本。

如果由于某种原因这是不可能的或不切实际的,这是你能做的最好的事情:

var bar = new foo();
var clones = clone(bar);
bar = clones[0];
barCopy = clones[1];

除非你诉诸令人难以置信的不优雅eval诡计。

我认为你真正想要的是只return new myClone(),永远不要使用bar.这实际上使事情变得更加优雅(如果需要,您可以将其称为bar_template或其他名称),因为您现在可以克隆原始模板。

你想让我解释我的评论,你去吧:

function replaceClones(){
    for(var i = 0; i < arguments.length; i++){
        var varName = arguments[i];
        this[varName] = getClone(this[varName]);
    }    
}
function getClone(obj){
    var Clone = function(){};
    Clone.prototype = obj;
    return new Clone();
}
replaceClones("varA","varB");

如果你想要另一个范围,只需使用

replaceClones.call(newScope,"varA","varB");