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