在node里,你可以根据代是运行了require('./something.js')还是node something.js,来告诉你的程序去做两件不同的事情。如果你想与你的一个独立的模块进行交互,这是很有用的。
if (!module.parent) { // 运行 `node something.js` app.listen(8088, function() { console.log('app listening on port 8088'); }) } else { // 使用 `require('/.something.js')` module.exports = app; }
更多信息,请看the documentation for modules
#16 - 给回调函数传递参数
在默认情况下,你无法将参数传给回调函数,如下:
function callback() {
console.log('Hi human');
}
document.getElementById('someelem').addEventListener('click', callback);
你可以采取JavaScript闭包的优点来给回调函数传参,案例如下:
function callback(a, b) { return function() { console.log('sum = ', (a+b)); } } var x = 1, y = 2; document.getElementById('someelem').addEventListener('click', callback(x, y));
什么是闭包呢?闭包是指一个针对独立的(自由)变量的函数。换句话说,闭包中定义的函数会记住它被创建的环境。了解更多请参阅MDN所以这种方式当被调用的时候,参数X/Y存在于回调函数的作用域内。
另一种方法是使用绑定方法。例如:
var alertText = function(text) {
alert(text);
};
document.getElementById('someelem').addEventListener('click', alertText.bind(this, 'hello'));
两种方法在性能上有一些略微区别,详情参阅jsperf
#15 - 使用更简单的类似indexOf的包含判断方式
原生的JavaScript没有contains方法。对检查字符串或字符串数组项中是否存在某值,你可以这样做:
var someText = 'JavaScript rules';
if (someText.indexOf('JavaScript') !== -1) {
}
// 或者
if (someText.indexOf('JavaScript') >= 0) {
}
但是我们再看看这些ExpressJs代码片段。
// examples/mvc/lib/boot.js for (var key in obj) { // "reserved" exports if (~['name', 'prefix', 'engine', 'before'].indexOf(key)) continue; // examples/lib/utils.js exports.normalizeType = function(type){ return ~type.indexOf('https://www.jb51.net/') ? acceptParams(type) : { value: mime.lookup(type), params: {} }; }; // examples/web-service/index.js // key is invalid if (!~apiKeys.indexOf(key)) return next(error(401, 'invalid api key'));
问题是~位运算符。"运算符执行操作这样的二进制表达式,但他们返回标准的JavaScript的数值."
他们将-1转换为0,而0在JavaScript中又是false。
var someText = 'text'; !!~someText.indexOf('tex'); // someText 包含 "tex" - true !~someText.indexOf('tex'); // someText 不包含 "tex" - false ~someText.indexOf('asd'); // someText 不包含 "asd" - false ~someText.indexOf('ext'); // someText 包含 "ext" - true String.prototype.includes()
在ES6(ES 2015)中介绍了includes()方法可以用来确定是否一个字符串包含另一个字符串:
'something'.includes('thing'); // true
在ECMAScript 2016 (ES7)中,甚至数组都可以这样操作,如indexOf:
!!~[1, 2, 3].indexOf(1); // true
[1, 2, 3].includes(1); // true
不幸的是,这只是在Chrome,Firefox,Safari 9或以上的浏览器中被支持。
#14 - arrow 函数(ES6)
介绍下ES6里的新功能,arrow函数可能会是个很方便的工具,用更少行数写更多代码。他的名字来源于他的语法,=>和小箭头->比就像一个“胖胖的箭头”。可能有些人知道,这种函数类型和其他静态语言如lambda表达式的匿名函数。它被称为匿名,因为这些箭头函数没有一个描述性的函数名。
那么这样有什么好处呢?
语法:更少的LOC,不用一次次的键入函数关键字。
语义:从上下文中捕捉关键字this。
简单语法案例:
看看下面的两段代码片段,他们做的是一样的工作。你能很快的理解arrow函数的功能。
// arrow函数的日常语法 param => expression // 可能也会写在括号中 // 括号是多参数要求 (param1 [, param2]) => expression // 使用日常函数 var arr = [5,3,2,9,1]; var arrFunc = arr.map(function(x) { return x * x; }); console.log(arr) // 使用arrow函数 var arr = [5,3,2,9,1]; var arrFunc = arr.map((x) => x*x); console.log(arr)