简单而强大的JavaScript技巧

本篇文章将会介绍和解析一些简单但是强大的JavaScript技巧. 这些技巧所有的JavaScript程序员都可以马上使用, 你不需要成为JavaScript高手才能理解这些.如果你还是新手, 而且读完所有这些技巧的详解和每种技巧是如果工作的以后运用它们, 你会写出更加简练高效的JavaScript程序.
强大的&&和||表达式
你可能在JavaScript库和JavaScript框架中已经见过它们了, 那么我们先由几个基本的例子开始:
Example 1:||
(或)
设置默认值,通常用:

function setKey(value){ if(!value){ value = "Default Value"; }}

用这个代替:

function setKey(value){ value = value || "Default Value";}

提示: JavaScript判断为假的值: null, false, 0, undefined, NaN和(空字符串). 记住像Infinity(无限大)这种 Number(感谢@xyzhanjiang 的指正) 的值是被判断为真不是假. 而NaN则被判断为假. 除了以上这些, 其他值全部被判断为真.

解析:- ||
操作符首先从左开始判断表达式的真假, 如果为真, 马上返回左边表达式返回的值; 如果左边表达式被判断为假, 则继续判断右边的表达式, 并返回右边表达式的值.- 如果value被判断为假, 会返回右边表达式的值. 换句话说, 如果value变量被判断为真, 则返回value的值.
Example 2:&&(并)
不要这么做:

function isAdult(age){ if(age && age > 17){ return true; }else{ return false; }}

用这个代替:

function isAdult(age){ return age && age > 17;}

解析:- &&
操作符从左开始判断表达式, 如果左边的表达式被判断为假, 则返回false(!注:如果左边表达式的值为0时,则返回0感谢@飞天鼠 的指正), 不管右边的表达式是否为真.- 如果左边的表达式为真, 则继续判断右边的表达式, 然后返回右边表达式结果.这变得越来越有趣了,不是吗?
Example 3:
不要这样做:

function checkLogin(userName){ if(userName){ logIn(userName); }else{ signUp(); }}

用这个代替:

function checkLogin(userName){ userName && logIn(userName) || signUp();}

解析:- 如果userName为真,则调用logIn函数并传递参数userName- 如果userName为假或者logIn
函数返回值为假(感谢@飞天鼠 的指正),则调用signUp
函数
Example 4:
不要这样做:

var user = {id:'this is id',log:'this is log'}, userId;if(user && user.log) { userId = user.id;}else{ userId = null;}

用这个代替:

var user = {id:'this is id',log:'this is log'}, userId;userId = user && user.log && user.id;

解析:- 如果user为真, 则调用user.log, 并检查user.log是否为真; 如果返回真, 则返回第三个表达式的返回值- 如果user为空, 返回null

下图为user.log存在的时候userId的值:


enter image description here
enter image description here

下图为user.log不存在的时候userId的值


enter image description here
enter image description here

强大的立即调用函数表达式
(什么是立即调用函数表达式, 何时使用它)IIFE(Immediately Invoked Function Expressions, 发音:"Iffy")是立即调用函数表达式的缩写形式, 它的语法大概如下:

(function () { // Do fun stuff​})();

这是一个立即调用的匿名函数, 它在JavaScript中有一些特别重要的作用.
它是如何工作的?
包围匿名函数的一对括号会把它变成函数表达式
或者变量表达式
.
这就相当于:

// 不带括号:​? = function () {};​​// 带括号:​(? = function () {});​// 函数被一个不知名的变量引用了, 一对括号把它包围了, 把它变成了一个匿名的函数表达式
同样的, 我们甚至可以创建一个命名的立即调用函数表达式:
(showName = function (name) {console.log(name || "No Name")}) (); // No Name​​showName ("Rich"); // Rich​showName (); // No Name
记住, 当你不用var
关键词创建变量的时候, JavaScript会自动判断该变量为全局变量
. 在上面的例子中是没有必要使用var
关键词的(因为你之后可能会调用它).
我们可以马上或者在这之后使用这个函数
但是我们不可以在之后调用匿名函数. 因为除非你创建匿名函数之后马上调用, 在这之后没有其他办法可以引用它. 这是匿名函数只可以马上调用它的原因.

当把匿名函数包含在一对括号里面时(字面量), 整个字面量会被运算,并且返回匿名函数的返回值. 它的返回值实质上是整个匿名函数自身, 所以我们只需要在这之后加上一对括号来马上调用它.

因此, 后面的一对括号等于告诉JavaScript编译器马上调用这个匿名函数, 所以它才会被称之为"立即调用函数表达式
".
因为JavaScript基于函数块的作用域规则, 在匿名函数内声明变量都是局部变量, 所以这些局部变量没办法直接从外部获取.
就像其他函数一样, 你可以向匿名函数设定参数和传递变量. 你可以根据这个特性, 利用匿名函数的作用域扩展它外围函数的作用域(即闭包).

什么时候应该使用它?
1.避免污染全局作用域IIFE
最广泛的用途是避免污染全局作用域. 已经有很多JavaScript库和JavaScript高手正在使用这种技巧, 尤其是在最流行jQuery插件的开发者中. 你也应该把这个技巧应用在你的程序的主要文件中(main.js).在这个例子中, 我使用了匿名函数把所有全局作用域的变量变成了局部变量, 所以现在全局作用域中还可以定义新的变量, 不用顾忌是否会和匿名函数内的变量在变量名上发生冲突(还包括其他库或者框架):
// 所有的代码包含在立即调用函数中(function () {
​var firstName = “Richard”;

function init () {
doStuff (firstName); // 在这里开始插入应用程序的代码...​
}
​​function doStuff () { // Do stuff here​}​​function doMoreStuff () { // Do more stuff here​}​​// 启动应用程序init ();
}) ();
2.用作条件选择器这种使用方式还没有被广泛所知, 但它是相当强大的. 你可以不调用一个命名函数来处理复杂的运算的. 注意在三目运算符(.. ? .. : ..
)中的两个匿名函数, 我尽可能多地加入空白来使语句看起来更容易理解:
var unnamedDocs = [], namedDocs = ["a_bridge_runover", "great_dreamers"];​​function createDoc(documentTitle) { var documentName = documentTitle ​ ?​ (function (theName) { var newNamedDoc = theName.toLocaleLowerCase().replace(" ", ""); namedDocs.push(newNamedDoc);​ return newNamedDoc; })(documentTitle);​​ :​​ (function () { var newUnnamedDoc = "untitled" + Number(namedDocs.length + 1); unnamedDocs.push(newUnnamedDoc); return newUnnamedDoc; })();​​ return documentName;}​createDoc("Over The Rainbow"); // over_the rainbow​​createDoc(); // untitled_4

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,976评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,249评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,449评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,433评论 1 296
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,460评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,132评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,721评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,641评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,180评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,267评论 3 339
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,408评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,076评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,767评论 3 332
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,255评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,386评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,764评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,413评论 2 358

推荐阅读更多精彩内容