Javascript 使用对象数组构造一个新对象,该对象将调用在原始数组中声明的函数

Javascript 使用对象数组构造一个新对象,该对象将调用在原始数组中声明的函数,javascript,arrays,object,Javascript,Arrays,Object,我正在为我的新网站项目使用JS路由器。路由器接受一个对象:键是URL地址,值是到达地址时将调用的函数 随着页面和子页面的数量越来越大,它很快就会变得混乱,特别是考虑到不同的页面需要调用不同的初始化函数initAccordion或initDataTables,等等 为了保持整洁,我考虑创建一个对象数组,其中包含页面名称和页面加载后需要调用的init函数。但是,我使用的解决方案使用eval: 这一切都很好,但是有没有办法让pages.init数组不带引号,并且对象创建者不使用eval?所以这些值看起

我正在为我的新网站项目使用JS路由器。路由器接受一个对象:键是URL地址,值是到达地址时将调用的函数

随着页面和子页面的数量越来越大,它很快就会变得混乱,特别是考虑到不同的页面需要调用不同的初始化函数initAccordion或initDataTables,等等

为了保持整洁,我考虑创建一个对象数组,其中包含页面名称和页面加载后需要调用的init函数。但是,我使用的解决方案使用eval:

这一切都很好,但是有没有办法让pages.init数组不带引号,并且对象创建者不使用eval?所以这些值看起来像这样的init:[initFoo,initBar]

所以我的问题是:有没有一种方法可以创建新的RouterPath对象,而不必构造一个字符串,然后对其运行eval?我应该坚持我所拥有的吗


请记住,routerPaths.home、routerPaths.people需要是从pages.init调用函数的函数

不需要通过函数的字符串名引用函数。只需像使用任何其他变量一样使用函数名。 变量页=[ { 姓名:home,, init:[initFoo,initBar] }, { 姓名:人民,, init:[initBar] } ];

并将init存根编写为普通闭包注意:必须在循环中使用let而不是var

var routerPaths = {};

for (var page of pages) {
    let init = page.init;

    routerPaths[page.name] = function() {
        init.forEach(function(fn) { fn() })
    }
}
如果您不能将ES6用于…of and let,请将其替换为'forEach:

pages.forEach(function(page) {
    var init = page.init;
    routerPaths[page.name] = function() {
        init.forEach(function(fn) { fn() })
    }
})

这是我正在使用的前端路由器。你的解决方案能在浏览器中运行吗?@DamianChrzanowski:为老版本的浏览器添加了一个示例,我试试看
pages.forEach(function(page) {
    var init = page.init;
    routerPaths[page.name] = function() {
        init.forEach(function(fn) { fn() })
    }
})
const initFoo=()=>{
    console.log("initFoo says hi");
}

const initBar=()=> {
    console.log("initBar says hi");
}

let pages = [
    {
        name: "home",
        init: [initFoo, initBar]
    },
    {
        name: "people",
        init: [initBar]
    }
];

let routerPaths = {
};

for (let page in pages) {
    let url = pages[page].name;
    let init = pages[page].init;
    Object.defineProperty( routerPaths ,  url , {
        value: ()=>{
            for(var item in init) {
                init[item]();
            }
        },  
        enumerable: true, // if enumerable is true then only you can see the people,home properties if you console.log
                          //if enumerable set to false you can not see the the property but you can still call routerPaths.people and it just works fine
    });
}
console.log(routerPaths);

routerPaths.home();  // as expected: initFoo says hi initBar says hi
routerPaths.people();  // as expected: initBar says hi