我正在学习本教程:http://vimeo.com/16961179教你如何用express.js制作视图和部分视图:
var products = [
{
id: 1,
name : 'Mac Book Pro',
description: 'Apple 13 inch Mac Book Pro notebook',
price: 1000
},
{
id: 2,
name : 'iPad',
description: 'Apple 64GB 3G iPad',
price: 899
}
];
module.exports.all = products;
module.exports.find = function(id) {
id = parseInt(id, 10);
var found = null;
productloop: for(product_index in products) {
var product = products[product_index];
if (product.id == id) {
found = product;
break productloop;
}
};
return found;
}
在本教程中,作者没有解释这部分内容。 我对循环部分特别困惑。 任何人都可以向我解释(我是一个JavaScript初学者)?
我理解顶部的products变量,但它看起来像是一个内部有其他数组的数组。
答案 0 :(得分:2)
该功能按产品ID搜索产品。
product
按顺序设置到产品数组中的每个产品。goto
)并返回产品(真实)。答案 1 :(得分:1)
你表达的内容是否更具可读性:
var products = [
{
id: 1,
name : 'Mac Book Pro',
description: 'Apple 13 inch Mac Book Pro notebook',
price: 1000
},
{
id: 2,
name : 'iPad',
description: 'Apple 64GB 3G iPad',
price: 899
}
];
module.exports.all = products;
module.exports.find = function(id) {
var i, product,
nProducts = products.length;
id = parseInt(id, 10);
for(i = 0; i < nProducts; ++i) {
product = products[i];
if (product.id === id) {
return product;
}
}
return null;
}
答案 2 :(得分:1)
首先,这是一个糟糕的代码。它可能会在最微小的变化时崩溃。 让我们从第一行开始。
var products = [
在全局上下文中声明变量。尽量避免这种情况。在全球范围内发生的一切都可能会崩溃。此外,数据封装有助于提高代码的模块性,从而允许您重用代码。
让我们看一下函数find():
module.exports.find = function(id) {
id = parseInt(id, 10);
var found = null;
productloop: for(product_index in products) {
var product = products[product_index];
if (product.id == id) {
found = product;
break productloop;
}
};
return found;
}
在JavaScript中,块不会引入范围。只有功能范围。函数中任何位置引入的变量在函数中的任何位置都可见。 JavaScript的块会让有经验的程序员感到困惑并导致错误,因为熟悉的语法会产生错误的承诺。
所以这个(var product = products[product_index];
)声明实际上并没有在每次迭代时声明一个新变量。
下一步。
product.id == id
==和!=运算符在比较之前输入强制。这很糟糕,因为它导致'\ t \ r \ n'== 0为真。这可以掩盖类型错误。 如果是函数find(),则运算符==不会导致错误,但这是更改代码时可能出现错误的位置。 始终使用===运算符。
for(product_index in products)
for in语句允许循环遍历对象的所有属性的名称。不幸的是,它还遍历了通过原型链继承的所有属性。当兴趣在数据属性中时,这具有提供方法功能的不良副作用。如果在没有意识到这种情况的情况下编写程序,那么它可能会失败。
每个for语句的主体应该包含在进行过滤的if语句中。它可以选择特定类型或范围的值,也可以排除函数,也可以从原型中排除属性。例如,
for (name in object) {
if (object.hasOwnProperty(name)) {
....
}
}
在您的代码中,'products'是一个数组,因此您可以确定它没有额外的属性。但!产品是全局变量,所以实际上它可以是任何东西。
我稍微重写了这个函数并解释了这段代码的作用。
module.exports.find = function(id) {
var found = null,
product;
id = parseInt(id, 10);
for (product_index in products) {
if (products.hasOwnProperty(product_index)){
product = products[product_index];
if (product.id === id) {
found = product;
break;
}
}
};
return found;
}
这很简单。该函数将产品ID作为参数(function(id)
),将其转换为数字(id = parseInt(id, 10);
)。然后使用循环(for(product_index in products)
)逐个运行产品数组,检查传递给函数标识符的相等性和当前产品的标识符(if (product.id == id)
)。如果它们相等,则停止迭代(break;
),将当前产品的值分配给变量“found”(found = product;
)并将结果返回给函数的调用者(return found;
)。
P.S。我真的不懂英语,所以请原谅我可能出现的错误。
答案 3 :(得分:1)
Products
是一个包含两个对象的数组。有些人可能称它们为“关联数组”,但它们只是对象。它们具有“属性”(如id
)和“值”:
var products = [{
id: 1,
name : 'Mac Book Pro',
description: 'Apple 13 inch Mac Book Pro notebook',
price: 1000
},{
id: 2,
name : 'iPad',
description: 'Apple 64GB 3G iPad',
price: 899
}];
module.exports 是您执行require('./products.js')
时节点程序实际看到的对象:
module.exports = {
// just pass along the whole array
all: products,
// method to find a product by id
find: function(id){
return products.filter(function(product){
return product.id == id
})[0] // we return the first element, at index zero
}
}
我将for in
循环替换为filter
method,应该让这里的内容更清晰。它将循环遍历products数组并为每个数组执行函数 - 如果结果为true
,则该项将添加到结果中,否则将被忽略。
使用此模块应该使用Express:
var products = require('./products.js')
app.get('/products', function(req, res){
// get the whole products array
products.all
// render page...
})
app.get('/products/:id', function(req, res){
// get product with id ':id' from URL (http://mysite.com/products/25)
var p = products.find(req.params.id)
// render page...
})