手机版

关于JavaScript的10个怪癖和秘密分享

时间:2021-10-18 来源:互联网 编辑:宝哥软件园 浏览:

原作者:Andy Croxall原链接:关于JavaScript翻译的十个古怪和秘密编辑:张新旭数据类型和定义1。Null是一个对象。在很多JavaScript类型中,有一个null类型,它有一个唯一的值null,也就是它的文字值,定义为一个完全没有任何意义的值。它的行为类似于一个对象,如下所示:检测代码:复制代码: alert(type of null);//弹出如下‘对象’截图:

虽然值类型显示“object”,但null不被视为对象实例。要知道,JavaScript中的值都是object实例,每个数值都是Number对象,每个对象都是Object对象。因为null没有值,很明显null不是任何东西的实例。因此,以下值等于false。复制代码如下:alert(对象的空实例);//false译者注:null也被理解为对象占位符。2.NaN是一个数值。NaN原本的意思是某个值不是数值,但它本身就是数值,不等于它本身。很奇怪。看下面的代码:复制代码如下: alert(类型为NAn);//弹出‘Number’提醒(NaN===NaN);//false。结果是下面的截图:

其实,NaN不等于任何东西。要确认某个东西是不是NaN,只能用isNaN.3 .没有关键字的数组相当于false(关于Truthy和Falsy)。下面是JavaScript的另一个优秀怪癖:复制的代码如下: alert(new Array()==false);//是真的。结果如下:

要知道这里发生了什么,你需要理解真理和谬误的概念。它们是真实的/虚假的。在JavaScript中,所有非布尔值都将内置一个布尔标志。当需要该值具有布尔行为时,将会出现该内置布尔值,例如,当您想要与布尔值进行比较时。因为苹果比不上Pear,所以当需要比较两种不同类型的JavaScript值时,会先弱化为同一类型。False、undefined、null、0、“”和NaN都弱化为false。这种强制转换并不总是存在的,只有当它被用作表达式时。看这个简单的例子:复制代码如下: var some var=0;alert(someVar==false);//以下截图为true的结果:

在上面的测试中,我们试图将数值0与布尔值false进行比较。因为两者的数据类型不兼容,所以JavaScript会自动将它们转换成统一且等价的true和false,其中0等于false(如上所述)。您可能已经注意到,在上面的一些值中没有空数组等同于false。仅仅因为空数组是一个奇怪的胚胎:它实际上属于truthy,但是当空数组与Boolean比较时,它的行为属于falsy。迷茫?这是有原因的。首先举一个验证空数组怪脾气的例子:复制代码如下: var someVar=[];//空数组alert(someVar==false);//结果true if(someVar)alert(' hello ');//执行alert语句,所以someVar把结果当成真,如下截图,连续弹出两帧:

译者注:造成这种差异的原因是,根据作者的说法,在数组中内置toString()方法时,比如直接alert,字符串会以join(“,”)的形式弹出,空数组自然就是空字符串,相当于false。请参考作者的另一篇文章,《Twisted logic: understanding truthy falsy》。然而,我个人感到惊讶的是,当一个空对象、一个空函数和弱等于真或假时,它都显示为假。为什么呢?真的是因为数组是个怪胎才需要特别考虑吗?为了避免强制转换的比较问题,可以使用强等号(===)代替弱等号(==)。复制的代码如下: var some var=0;alert(someVar==false);//结果为真0属于falsy alert(someVar===false);//结果为假零是一个数值,而不是布尔值。结果是下面的截图(win7ff4):

如果您想探索一些独特的特性,例如JavaScript中的类型转换,您可以参考官方文档规范:ECMA-262正则表达式4的第11.9.3节。replace()接受回调函数。这是JavaScript最不为人知的秘密之一,最早是在v1.3中引入的,在大多数情况下,replace()的用法类似于下面这样:复制代码如下: alert ('10 13 21 48 52 '。替换(/\ d/g,' *);//用*替换所有数字这是一个简单的替换,一个字符串和一个星号。但是如果我们想在替换发生时有更多的控制权呢?我们只想替换30以下的值。我们做什么呢目前,仅仅依靠正则表达式是我们力所不及的。我们需要借助回调函数的东风来处理每一场比赛。复制代码如下:alert ('10 13 21 48 52 '。replace (/\ d/g,function(match){ return par sent(match)30?*”:匹配;}));每次匹配完成后,JavaScript应用回调函数将匹配内容传递给匹配参数。然后,根据回调函数中的过滤规则,返回星号或匹配本身(不发生替换)。以下截图:

5.正则表达式:不仅仅是匹配和替换,很多javascript工程师只通过匹配和替换来处理正则表达式。但是JavaScript定义的不仅仅是这两个与正则表达式相关的方法。值得一提的是,test()的工作方式与match()类似,但其返回值不同:test()返回一个布尔类型来验证是否匹配,其执行速度高于match()。复制代码如下: alert(/\ w { 3 },}/。测试(' hello ');//弹出‘真’。上面一行代码用于验证字符串是否有三个以上的普通字符。显然,‘你好’符合要求,所以弹出‘真’。结果如下:

我们还应该注意RegExp对象,它可以用来创建动态正则表达式对象。例如,复制代码如下:函数find word (word,string){ var instance soft word=string . match(new regexp(' \ \ b ' word ' \ \ b ',' ig ');警报(instance of word);} find word(‘汽车’,‘卡尔去买车了,但是忘了带信用卡。’);这里,我们基于参数词动态创建匹配验证。该测试代码的功能是选择单词car,而不区分大小。眼睛一扫,英文句子里只有一个字是car,所以这里的表现只有一个字。\b用于指示单词边界。结果如下:

和功能范围。6.你可以假装成范围作用域,用来决定哪些变量是可用的。独立的JavaScript(如JavaScript不是正在运行的函数)在窗口对象的全局范围下运行,在任何情况下都可以访问窗口对象。但是,在函数中声明的局部变量只能在此函数中使用。复制的代码如下: var animal=' dog函数getAnimal(形容词){ alert(形容词' ' this . animal);} getAnimal('可爱');//弹出‘可爱的狗狗’,我们的变量和函数在全局范围内声明。因为这指向当前范围,所以在本例中它是窗口。因此,函数寻找window.animal,也就是“狗”。到目前为止,一切正常。但是,事实上,我们可以让函数在不同的范围内运行,而忽略它自己的范围。我们可以使用一个名为call()的内置方法来模拟作用域。复制的代码如下: var animal=' dog函数getAnimal(形容词){ alert(形容词' ' this . animal);};var myObj={ animal : ' camel ' };getAnimal.call(myObj,'可爱');//弹出的‘可爱的骆驼’call()方法中的第一个参数可以在函数中冒充这个,所以这里的this.animal实际上是myObj.animal,意思是‘骆驼’。以下参数作为普通参数传递给函数体。另一个相关的方法是apply()方法,其作用类似于call()。不同的是,传递给函数的参数是以数组形式表示的,而不是自变量。因此,如果用apply()表示上述测试代码,则为:复制代码如下:getanimal.apply (myobj,['可爱']);//功能参数在演示页面以数组形式发送,点击第一个按钮的结果如下:

点击第二个和第三个按钮的结果如下:

7.函数可以自己执行。下面这个很OK:复制代码如下:(function(){ alert(' hello ');})();//弹出‘你好’。这里的解析很简单:因为()解析,所以声明一个函数并立即执行它。你可能会奇怪为什么要这样做(指的是直接的butt()调用),这似乎有点矛盾:函数通常包含我们以后要执行的代码,而不是当前的分析和执行,否则,我们不需要将代码放在函数中。自执行函数的另一个很好的用途是在延迟代码中使用绑定变量值,例如事件回调、超时和间隔。示例:复制代码如下: var someVar=' hellosetTimeout(函数(){ alert(someVar);}, 1000);var someVar='再见';在论坛里,Bies总是问为什么超时弹出的是再见而不是你好。答案是超时中的回调函数在运行之前不会分配someVar变量的值。那时候,someVar已经被再见改写了很久。标准电子格式为这个问题提供了一个解决方案。someVar值不是像上面那样隐式指定超时回调,而是直接作为参数传入。效果显著,也就是说我们引入并隔离了someVar值,保护其不被地震海啸或女友的愤怒咆哮所跟随而改变。复制的代码如下: var someVar=' hellosetTimeout()(函数(someVar){ return function(){ alert(someVar);} })(someVar),1000);var someVar='再见';风和水轮流转。这一次,这里弹出的是你好。这是函数参数和外部变量的点差。比如最后一个按钮弹出如下:

浏览器8。火狐读取并返回RGB格式的颜色,而不是十六进制。直到现在,我还没有真正理解Mozilla为什么会这样。要有一个清晰的认识,看下面的例子:复制代码如下:-# some para { color : # f90;} - p id='somePara '你好,世界!/p脚本var ie=navigator . appversion . indexof(' MSIE ')!=-1;var p=document . getelementbyid(' some para ');警戒p . currentstyle . color : getComputedStyle(p,null)。颜色);/script大多数浏览器的结果是ff9900,但FireFox的结果是rgb(255,153,0)和rgb。通常在处理颜色时,我们需要花费大量的代码来将RGB颜色转换成Hex。以下是以上代码在不同浏览器下的结果:

其他杂项。0.1 0.2!==0.3这个奇怪的问题不仅出现在JavaScript中,也是计算机科学中常见的问题,影响了很多语言。标题输出的结果是0.30000000000000000004。这就是所谓的机器精度问题。当JavaScript试图执行(0.1 0.2)这一行代码时,它会把值转换成自己喜欢的二进制味道。这就是问题的由来。其实0.1不是0.1,而是它的二进制形式。本质上,当你写下这些值时,它们注定会失去准确性。你可能只想得到一个简单的两位小数,但你得到的(根据克里斯派恩的笔记)是一个二进制浮点计算。比如要把一个段落翻译成简体中文,结果是繁体中文,还是有一些区别的。与此相关的问题一般有两种处理方式:转换成整数再计算;计算后,转换为所需的十进制内容来调整您的逻辑,并将允许的范围设置为不是指定的结果。例如,我们不应该如下复制代码: varnum1=0.1,num2=0.2,应该等于=0.3;alert(num 1 num 2==should qual);//false并尝试这样做:复制代码如下:alert (num1num2应等于-0.001num1num2应等于0.001);//真10。未定义的可以被定义(defined)我们以一个小怪癖结束。可能听起来很奇怪,undefined在JavaScript中不是一个保留字,尽管它有特殊的含义,并且是确定变量是否未定义的唯一方法。因此;复制代码如下: var someVaralert(someVar==未定义);//说明是真的。到目前为止,一切看似平静正常,但剧情总是血腥的:副本代码如下: undefined='我没有undefined!var someVaralert(someVar==未定义);//显示false!这就是为什么jQuery源代码中最外层的闭包函数应该有一个不被传入的未定义的参数,以保护未定义的不被一些外部的不良吸收。

版权声明:关于JavaScript的10个怪癖和秘密分享是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。