9个Javascript的知识点 (9 JavaScript Tips You May Not Know)

文章有代码部分,如果有阅读困难,请到原文阅读:https://blog.jing.do/4212

前言:本篇文章是我在查询时偶然间发现的,虽然年代久远但是依旧非常适合入门学习,特此翻译下分享给大家,顺便给大家加了一些备注方便阅读(特意加粗刷存在感)。原文全文和链接在最后

———————-以下是正文———————-

备注:本篇文章是34岁的程序员Ayman Hourieh在2006年发布的。我找到了他网站的链接,但是网站已经不存在了。我用Wayback Machine找到了文章的镜像。为了让更多人看到把他摘录分享出来。我只做了一些链接的修改。

JavaScript是一个功能强大的面向对象语言。表面上看他他和JAVA和C非常相似,但是他却截然不同,其核心在于JavaScript更像一个功能性语言。本篇文章是一些JavaScript的小提示,一部分提供一些类C语言的功能模拟,另一部分是想要提高性能并探讨下脚本语言中一些比较难懂的东西。索引如下:

多用途的Array

队列

二叉树

String Concatenation 对比 Array.join

给对象绑定方法

使用自定义排序

Assertion

静态局部变量

null, undefined, and delete

深层嵌套

使用Firebug

$ 和 $$

console.log(format, obj1, …)

console.trace()

inspect(obj)

多用途的Array

尽管JavaScript在数据结构方面看起来很奇特,他的Array比其他编程语言(如C ++或Java)用途更加广泛。 它通常用作数组或关联数组,后面将演示如何将其用作堆栈,队列和二叉树。 复用Array而不是编写其他的数据结构有两个好处:首先,不用浪费时间去重写已经存在的功能,其次,内置浏览器对JavaScript的运行将更高效。

大家都知道栈是后进先出:最后插入的会被最先移除。array有两个方法来实现栈的功能。他们是push()和pop()。push()用于插入item到array的尾部,而pop()则用于移除并返回最后一个item。以下是代码的实例:

varstack=[];stack.push(2);// 当前栈是 [2]stack.push(5);// 当前栈是 [2, 5]vari=stack.pop();// 当前栈是 [2]alert(i);// 显示 5

队列

队列是先进先出的:现行插入的将会被最先移除。array可以用push()和shift()来实现队列。push()用于插入item到尾部,shift()用于移除第一个item。案例如下:

varqueue=[];queue.push(2);// 现在的队列 [2]queue.push(5);// 现在的队列 [2, 5]vari=queue.shift();// 现在的队列 [5]alert(i);// 显示 2

值得注意的是,array还有一个unshift()的函数。这个函数用于将item放到array的头部。所以栈也可以使用unshift()/shift(),而队列可以用unshift()/pop()。

如果这些函数名称让你迷茫了(译者注:因为unshift()是处理头部,所以相对应的栈需要从头部出去,队列需要换到尾部),你可以给他们取个别名,比如,创建队列的方法名为add和remove:

varqueue=[];queue.add=queue.push;queue.remove=queue.shift;queue.add(1);vari=queue.remove();alert(i);

二叉树

二叉树是在树的节点表示数据。每个节点有一个数据并且有两个子节点(左叉树和右叉树)。在C语言里,这种数据结构通常使用指针来实现。这种实现方法也可以在JavaScript中使用对象和引用来实现。然而,对于一些小的二叉树,有一种更简单便捷的方法,array的第一个item作为树的头。 如果可以使用以下公式计算节点i,则索引左右节点:

leftChild(i)=2i+1rightChild(i)=2i+2

这张图揭示了这个算法: (来自于Wikipedia):

正如你所看到的,这种方法并不是JavaScript的独有之处,但是在处理小的二叉树时非常有用。 例如,您可以编写自己的函数来获取和设置节点的值或子节点,并遍历二叉树,这些方法与做计算或for循环一样简单。但是,这种方法的缺点是随着树的深度增加,浪费的存储空间越来越多。

String Concatenation 对比 Array.join

大家都知道,如果做太多的字符串链接会让性能下降(译者注:不知道的去补课),并且这个非常容易避免。如果你想要用各个字符来组成一个字符串,最差的方法是使用+把所有的字符结合到一起:

str='';for(/* each piece */){str+=piece;// bad for performance!}returnstr;

这种方法将使用太多的字符串链接,会让性能枯竭。

在JavaScript中有个更好的办法,就是Array.join(),他可以让所有array内的元素连接成一个字符串:

vartmp=[];for(/* each piece */){tmp.push(piece);}str=tmp.join(' ');// 用空格作为分隔符returnstr;

该方法不会受到额外的字符串对象的影响,通常执行的非常高效

给对象绑定方法

任何使用JavaScript事件的人都可能遇到了一种情况,他们需要将对象的方法分配给事件处理程序。 这里的问题是事件处理程序会被HTML调用,即使它们最初被绑定到另一个对象。 为了解决这个问题,我用一个函数将对象和方法绑定; 它他会运行对象和方法,并返回一个在该对象调用该方法的函数。 我在Prototype中找到了一个窍门,并且写了以下函数来在不包含Prototype的项目中使用它:

functionbind(obj,method){returnfunction(){returnmethod.apply(obj,arguments);}}

如何使用:

varobj={msg:'Name is',buildMessage:function(name){returnthis.msg+' '+name;}}alert(obj.buildMessage('John'));// displays: Name is Johnf=obj.buildMessage;alert(f('Smith'));// displays: undefined Smithg=bind(obj,obj.buildMessage);alert(g('Smith'));// displays: Name is Smith

使用自定义排序

排序是一个常见的工作。 JavaScript提供了一种排序数组的方法。 但是,该方法默认按字母顺序排列 —— 非字符串元素在排序之前被强制转换为字符串,这个使得数字排序会有意想不到的结果:

varlist=[5,10,2,1];list.sort()// list is now: [1, 10, 2, 5]

这个解释很容易: 数字被强制转换成了字符串,所以10编程了’10’而2变成了’2’,那么JavaScript对比两个字符串的时候,先对比第一个字符。如果str1的第一个字符出现在字符集中的第一个字符之前,则str1被认为是“小于”str2。 在我们的情况下,’1’在’2’之前,所以’10’小于’2’。

幸运的是,JavaScript提供一个重写机制,让我们可以自定义如何排序,我们用a和b两个元素最为例子:

如果a

如果a=b,返回0

如果a>b,返回大于0

写这样的程序比较容易:

functioncmp(a,b){returna-b;}

我们现在可以使用这个方法来做排序:

varlist=[5,10,2,1];list.sort(cmp);//listisnow:[1,2,5,10]

Array.sort()牛逼的地方是允许更复杂的排序。 假设你有一个论坛帖子,每个帖子看起来像:

varpost={id:1,author:'...',title:'...',body:'...'}

如果你想用id排序,只需要创建以下函数:

functionpostCmp(a,b){returna.id-b.id;}

可以说,使用浏览器的方法进行排序将比在JavaScript中实现排序函数更有效。 但是,数据应该在服务器端进行排序。所以,除非必要,否则不应该让数据在客户端排序。

Assertion

Assertion是一种常用的调试技术,它用于确保表达式在执行期间计算为真。 如果表达式计算为假,则表示代码中可能出现的错误。 JavaScript缺少一个内置的Assertion功能,但幸运的是,它很容易编写一个。 如果传递的表达式的计算结果为假,以下实现会抛出AssertException类型的异常:

functionAssertException(message){this.message=message;}AssertException.prototype.toString=function(){return'AssertException: '+this.message;}functionassert(exp,message){if(!exp){thrownewAssertException(message);}}

自己抛出异常并不是非常有用,但是当与有用的错误消息或调试工具结合使用时,您可以检测到有问题的部分。

您还可以使用以下代码段检查异常是否为Assertion异常:

try{// ...}catch(e){if(einstanceofAssertException){// ...}}

该函数的使用类似于C或Java:

assert(obj!=null,'Object is null');

如果obj碰巧为null,Firefox将在JavaScript控制台中打印以下消息:

uncaughtexception:AssertException:Objectisnull

Static Local Variables

大家知道,一些语言像C ++,他们有静态变量的概念,用于函数调用。 JavaScript并不支持此技术。 然而,“功能也是对象”让这个功能成为可能。 方法是:将静态变量变为函数的属性。 假设我们要创建一个计数器函数:

functioncount(){if(typeofcount.i=='undefined'){count.i=0;}returncount.i++;}

当第一次调用count时,count.i是未定义的,所以if条件为true,count.i为0。因为我们将变量存储为一个函数属性,它将在函数调用之间保留它的值, 因此它可以被认为是一个静态变量。

这里有个性能提升小技巧:

functioncount(){returncount.i++;}count.i=0;

虽然第一个例子将Count的所有逻辑封装在主体中,但第二个例子更为有效。

null, undefined, and delete

因为JavaScript有undefined和null所以他不同于其他语言。null是一个特别的数值,他表示没有数值。null会被认为一个特别的对象,因为typeof null会返回null。

undefined表示变量没有被定义,或者定义了但没有给数值。以下情况都会显示undefined:

// i is not declared anywhere in codealert(typeofi);vari;alert(typeofi);

虽然undefined和null是两个不同的类型,但是如果使用 == ,会被判定为相等,但是如果是 === 则不等。

JavaScript还有一个删除操作符,”undefines”一个属性,可以将其应用于对象属性和数组成员,使用var声明的变量不能被删除,而是隐式声明(implicitly declared )的变量可以:

varobj={val:'Some string'}alert(obj.val);// displays 'Some string'deleteobj.val;alert(obj.val);// displays 'undefined'

深层嵌套

如果您需要在深层嵌套对象上执行多个操作,最好将其引用到临时变量中,而不是每次对其进行解引用。 例如,假设您想在文本字段上执行一系列操作:

document.forms[0].elements[0]

建议您存储到变量中,并使用此变量而不是以上构造:

varfield=document.forms[0].elements[0];// Use field in loop

每个点都导致一个操作来检索一个属性,在一个循环中,这些操作是相加的,所以最好做一次,将对象存储在变量中并重新使用它。

Using Firebug

Firefox有一个非常棒的扩展,用于调试名为Firebug的JavaScript代码。 它提供一个具有断点和堆栈视图的调试器,以及一个JavaScript控制台。 它还可以监视Ajax请求。 此外,扩展提供了一组JavaScript函数和对象来简化调试。 您可以在Firebug的文档页面中详细研究它们。 这里有一些我觉得有用的:

$ and $$

熟悉Prototype的人马上就认出他们了,

$() 接受一个字符串参数,并返回其ID是传递的字符串的DOM元素。(译者注:Jquery

$('nav')// returns the element whose id is #nav.

$$()返回DOM的数组

$$('div li.menu')// returns an array of li elements that are// located inside a div and has the .menu class

console.log(format, obj1, …)

console对象提供显示log消息的方法,这个将比alert更加好用,console.log()有点像C里面的printf,他会将输入转化为字符串在console中展示:

vari=1;console.log('i value is %d',i);// prints:// i value is 3

console.trace()

此方法打印一个堆栈跟踪调用它。 它不需要输入参数

inspect(obj)

该功能需要一个参数。 它切换到检查选项卡并检查传递的对象。

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

推荐阅读更多精彩内容

  • 第5章 引用类型(返回首页) 本章内容 使用对象 创建并操作数组 理解基本的JavaScript类型 使用基本类型...
    大学一百阅读 3,231评论 0 4
  • 原文: https://github.com/ecomfe/spec/blob/master/javascript...
    zock阅读 3,371评论 2 36
  • Repo是干什么的? 用来统一管理Android源代码的工具 Repo命令 核心形式:repo 列如: re...
    wusp阅读 1,308评论 0 0
  • 今天我们一起来学习一本书叫《正向力》。 激发个人正向力,提升团队战斗力,也就是怎样通过培养正向力,来提升一个人的幸...
    听雨廖哥阅读 252评论 0 0
  • 不知道删除了多少文字 更不知道为什么乱七八糟 我觉得好像 写了我的出生 回忆的我的成长 记录的爱情 感受了亲情 都...
    窮奇阅读 189评论 2 1