Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/465.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用源对象中所有方法的修改版本创建对象_Javascript_For In Loop - Fatal编程技术网

Javascript 使用源对象中所有方法的修改版本创建对象

Javascript 使用源对象中所有方法的修改版本创建对象,javascript,for-in-loop,Javascript,For In Loop,我想创建一个对象,该对象修改了源对象中所有方法的版本,但在中使用for…时遇到问题 如果这是我的源对象: var raw = {}; raw.add = function(a,b){return a + b;} raw.sub = function(a,b){return a - b;} raw.neg = function(a){return -a;} raw.sqrt = function(a){return Math.sqrt(a);} 如果我在字符串数组中重新创建属性列表,它会起作用:

我想创建一个对象,该对象修改了源对象中所有方法的版本,但在中使用for…时遇到问题

如果这是我的源对象:

var raw = {};
raw.add = function(a,b){return a + b;}
raw.sub = function(a,b){return a - b;}
raw.neg = function(a){return -a;}
raw.sqrt = function(a){return Math.sqrt(a);}
如果我在字符串数组中重新创建属性列表,它会起作用:

var mod2 = Object.create(raw);
var proplist = ["add", "sub", "neg", "sqrt"];
proplist.forEach(function(prop){

    mod2[prop] = function(){
        var arglist = [].slice.apply(arguments);
        var out = [];
        if(arglist.length == 1){
            [].concat(arglist[0]).forEach(function(d){ out.push(raw[prop](d)); });
        }
        else if(arglist.length == 2){
            [].concat(arglist[0]).forEach(function(d1){
                [].concat(arglist[1]).forEach(function(d2){
                    out.push(raw[prop](d1,d2));
                })
            });
        }
        return out;
    }
});
但是我尝试使用..in的方法无效,新对象中的所有方法都将执行“sqrt”:

自动迭代方法的最佳方式是什么?


<script>
    var raw = {};
    raw.add = function () { console.log('add default method'); }
    raw.sub = function () { console.log('sub default method'); }
    raw.neg = function () { console.log('neg default method'); }
    raw.sqrt = function () { console.log('sqrt default method'); }
    console.log('*****************');
    console.log('before modifying');
    console.log('*****************');
    raw.add();
    raw.sub();
    raw.neg();
    raw.sqrt();
    var proplist = ["add", "sub", "neg", "sqrt"];
    console.log('*****************');
    console.log('after modifying');
    console.log('*****************');
    console.log('');
    var modified = Object.create(raw);
    for (prop in proplist) {
        if (prop == 0)
            console.log('rewriting methods and calling methods inside loop................');
        modified[proplist[prop]] = function () { console.log(proplist[prop] + ' method  modified, ' + proplist.length + ' argument passed') }
        modified[proplist[prop]]();
    }
    console.log('');
    console.log('trying call methods after loop is done................');
    modified.add();
    modified.sub();
    modified.neg();
    modified.sqrt();
    console.log('...it is becaouse "prop" variable in loop holding last count number ' + prop);
</script>
var raw={}; raw.add=函数(){console.log('add default method');} raw.sub=函数(){console.log('sub-default方法');} raw.neg=函数(){console.log('neg default method');} raw.sqrt=function(){console.log('sqrt default method');} console.log('******************'); console.log('修改前'); console.log('******************'); raw.add(); raw.sub(); raw.neg(); raw.sqrt(); var proplist=[“添加”、“子”、“负”、“sqrt”]; console.log('******************'); console.log('修改后'); console.log('******************'); 控制台日志(“”); var modified=Object.create(原始); 用于(proplist中的道具){ 如果(prop==0) log('rewriting methods and calling methods inside loop………..); 修改后的[proplist[prop]]=function(){console.log(修改了proplist[prop]+'方法,'+proplist.length+'传递的参数')} 修改了[proplist[prop]](); } 控制台日志(“”); log('循环完成后尝试调用方法…………'); modified.add(); 修改的.sub(); 修改后的.neg(); 修改的.sqrt(); log(“…这是因为在循环中使用“prop”变量来保存最后一个计数编号“+prop”);
多亏了arnold.NET.JS的回答澄清了问题,我发现闭包是解决问题的一种方法:

var raw = {};
raw.add = function(a,b){return a + b;}
raw.sub = function(a,b){return a - b;}
raw.neg = function(a){return -a;}
raw.sqrt = function(a){return Math.sqrt(a);}

var mod = Object.create(raw);
for(prop in raw){

    mod[prop] = (function(){

        var propname = prop;
        function f(){
            var arglist = [].slice.apply(arguments);
            var out = [];
            if(arglist.length == 1){
                [].concat(arglist[0]).forEach(function(d){ out.push(raw[propname](d)); });
            }
            else if(arglist.length == 2){
                [].concat(arglist[0]).forEach(function(d1){
                    [].concat(arglist[1]).forEach(function(d2){
                        out.push(raw[propname](d1,d2));
                    })
                });
            }
            return out;
        }
        return f;
    })();
}

第二个实现的问题是,您在新方法(稍后将调用)中使用了
prop
,但是创建
prop
for
循环在稍后调用该方法时已经运行完成,因此
prop
不再是正确的值(它将始终是最后一个属性)。在我的实现中,我通过在IIFE(立即调用的函数表达式)中捕获
prop
,修复了这一问题,因此每次通过
for
循环时,它都会被单独冻结。您的第一个实现没有这个问题,因为您使用的是
.forEach()
在属性数组上,该数组使用回调函数,可自动将
prop
的值捕获到闭包中


下面是对您的实现进行这些更改的结果:

  • 添加一个iLife以冻结
    prop
    的值,以便在新方法中使用
  • 添加额外的检查以确保我们复制的方法不是继承的,而是函数
  • 已将
    raw
    初始化为普通对象,因为我看不出有任何理由在此处使用
    object.create()
  • 守则:

    var raw = {};
    raw.add = function(a,b){return a + b;}
    raw.sub = function(a,b){return a - b;}
    raw.neg = function(a){return -a;}
    raw.sqrt = function(a){return Math.sqrt(a);}
    
    var modified = {};
    for (prop in raw) {
        if (raw.hasOwnProperty(prop) && typeof raw[prop] === "function") {
            (function (prop) {
                modified[prop] = function () {
                    var arglist = [].slice.apply(arguments);
                    var out = [];
                    if (arglist.length == 1) {
                        [].concat(arglist[0]).forEach(function (d) {
                                out.push(raw[prop](d));
                        });
                    } else if (arglist.length == 2) {
                        [].concat(arglist[0]).forEach(function (d1) {
                            [].concat(arglist[1]).forEach(function (d2) {
                                out.push(raw[prop](d1, d2));
                            })
                        });
                    }
                    return out;
                }
            })(prop);
        }
    }
    

    工作演示:

    您的
    for(原始道具)
    for循环可能工作得很好(在我看来还行)。你想在函数中实现什么。这看起来比我想象的要复杂得多,但我不知道你想用它实现什么。在本例中,我试图获得处理数组而不是标量参数的原始方法的版本。在修改的对象中,每个在单个数组参数中对每个元素进行运算,两个参数方法对其参数(arrayA,arrayB)中所有可能的元素组合(a,b)执行运算,并返回所有这些结果的数组。我想知道实现这一点的更好方法。
    Object.keys(raw).forEach(function() {…})
    会的。@Bergi-所以在你看来,每个问题谁的解决方案最终是创建一个闭包都是重复的-不管问题的其余内容是什么?不管答案和评论中讨论了多少其他问题?至少他完全致力于每个意义上的闭包,即使这会有所帮助,他也会问题是:该怎么做?太好了,谢谢。我使用了[].concat()以便将任何非数组参数转换为数组。在JSFIDLE中,语句
    modified.add(1,[4,3])
    除非我替换那些concat语句,否则不起作用。正确的方法是什么?@goutos19-我不知道这是一种合法的参数形式(一个数组,一个非数组)。您没有记录参数可能采用的形式。这将有助于我们研究更简单的方法来完成代码主体(我仍然认为可以简化),但我没有进行重大更改,因为我不确定你的输入规范是什么。好吧,我想你可以把concat的东西放回去。我很好奇,你用什么函数来返回所有可能的参数组合的结果?@goutos19-我把concat的东西放回去,并将你的测试用例添加到我的JSFIDLE中。这是我的第一个t我在这里问了一个问题,我会记住这一点,下次会说得更具体一些。我并不是想敲敲你的答案,因为你的答案肯定满足我指定的所有要求-谢谢。我想像这样处理数组参数,以便sqrt可以返回可能的正解和负解,并让它们在计算中传播。
    var raw = {};
    raw.add = function(a,b){return a + b;}
    raw.sub = function(a,b){return a - b;}
    raw.neg = function(a){return -a;}
    raw.sqrt = function(a){return Math.sqrt(a);}
    
    var modified = {};
    for (prop in raw) {
        if (raw.hasOwnProperty(prop) && typeof raw[prop] === "function") {
            (function (prop) {
                modified[prop] = function () {
                    var arglist = [].slice.apply(arguments);
                    var out = [];
                    if (arglist.length == 1) {
                        [].concat(arglist[0]).forEach(function (d) {
                                out.push(raw[prop](d));
                        });
                    } else if (arglist.length == 2) {
                        [].concat(arglist[0]).forEach(function (d1) {
                            [].concat(arglist[1]).forEach(function (d2) {
                                out.push(raw[prop](d1, d2));
                            })
                        });
                    }
                    return out;
                }
            })(prop);
        }
    }