当前位置: 首页 > Web前端 > HTML

重学前端JavaScript(五)JavaScript中的相关问题

时间:2023-04-02 19:17:01 HTML

本文主要是winter提出的一些问题加上自己的一些思考。如果有不对的地方希望大家指出。1.为什么有些编程规范要求使用void0而不是undefined?本文主要介绍JavaScript中的属性描述符、ES6中的模块、箭头函数。未定义类型的值是未定义的。当一个变量声明没有被赋值时,它的值是未定义的。undefined是全局对象的属性,这意味着它是全局范围的##variable##。它##不是关键字和保留字##,这是JavaScript语言公认的设计错误之一。undefined在全局范围内不能被篡改,但在非全局范围内(如函数)可以作为标识符(变量名)重新赋值。void操作可以将任意表达式变成undefined,所以为了避免无意的篡改,建议使用void0来获取undefined值。void运算符:计算给定的表达式并返回未定义。使用void表达式。一般使用void(0)(相当于void0)。表达式:表达式是由运算符组成的语法结构,运算产生结果。每个表达式都会产生一个值,该值可以放在任何需要值的地方。变量a=3+2;//3+2是表达式varb=(function(){return25;})();//(function(){return25;})()是表达式statement:语句可以理解为一种行为。循环语句和if语句是经典语句。程序由一系列语句组成。语句是由“;(分号)”分隔的句子或命令。它说“只有表达式而没有其他语法元素的语句”。如果你加一个“;”表达式后的分隔符,这句话称为“表达式语句”。JavaScript中的一般语句分为以下几类:(1)声明语句:变量声明和函数声明(2)赋值语句(3)控制语句:可以改变语句的执行顺序,包括条件语句和循环语句,以及特殊labelstatements(4)Expressionstatements:这些语句也可以用作没有最后分号的表达式。常见的有:object(new,delete),functioncall(函数执行,必须有返回值)等。参考自:MDN--undefinedMDN--void2.字符串有最大长度吗?String的最大长度为2^53-1,所谓最大长度不是字符数,而是字符串的UTF16编码。我们的字符串操作charAt、charCodeAt、length等方法都是针对UTF16编码的。因此,字符串的最大长度实际上受字符串编码长度的影响。3、为什么0.1+0.2不等于0.3?解释1:根据双精度浮点数的定义,Number类型的有效整数范围是-0x1fffffffffffff到0x1ffffffffffffff,所以Number不能准确表示这个范围之外的整数。浮点运算的精度问题会导致左右方程的结果并不严格相等,而是相差一个很小的值。解释2:对于计算机来说,两个数以二进制形式相加,结果呈现时再转为十进制。先将IEEE754双精度64位浮点数转换成对应的二进制,再进行成对运算。当小数的二进制表示法表示的有限数超过52位时,在JavaScript中无法准确存储,此时会出现舍入错误。因此,碱基之间的转换和顺序的操作可能会损失精度。只要这两步出现精度损失,计算结果就会有偏差。补充问题:1.如何让0.1+0.2==0.3?不用换算,用Math.abs(0.1+0.2-0.3)<=Number.EPSILON判断方程左右两边之差的绝对值是否小于Minimumprecision。Number.EPSILON:ES6在Number对象之上添加了一个非常小的常量Number.EPSILON。根据规范,它表示1和大于1的最小浮点数之间的差。(来自ECMAScript6入门)2.为什么0.2+0.3=0.5?这个在参考文章的第一篇可以看到,主要是在进行计算的时候满足了精度计算的要求。扩展:JavaScript使用Number类型来表示数字(整数和浮点数),遵循IEEE754标准通过64位来表示数字。在内存中,bit0:符号位,0表示正数,1表示负数(s)。第1至11位:存储指数部分(e)。第12至63位:存储小数部分(即有效数字)f。注意:当添加大于9007199254740992(Math.pow(2,53))的数字时,精度也会丢失。解释2参考文章:0.1+0.2不等于0.3?为什么JavaScript会有这种“骚”操作?JS的理解0.1+0.20.1+0.2=0.30000000000000004怎么理解4.为什么加在对象上的方法可以用在基本类型上?为了方便对基本类型值的操作,ECMAScript提供了几种特殊的引用类型:Boolean、Number、String、Symbol。每当读取到一个基本类型的值时,就会在后台创建一个对应的基本封装类型的对象,这样我们就可以调用一些方法来操作数据。基本封装类型的操作过程:lets1='sometext';让s2='s1.substring(2)';后台自动补全处理:1)创建String类型的实例2)在实例上调用指定的方法3)销毁这个实例基本包装类型和引用类型的主要区别在于对象的生命周期。使用new运算符创建的引用类型的实例保留在内存中,直到执行流离开当前范围。自动创建的基本包装类型对象仅在执行一行代码的那一刻存在,然后立即被销毁。因此,不能在运行时将属性和方法添加到基本类型的值中。资料来源:JavaScript高级编程(第3版)基本包装器类型进一步的问题:实现if(a==1&&a==2&&a==3)为真让a={val:1,toString(){returnthis。值++;},valueOf(){返回this.val++;}}if(a==1&&a==2&&a==3){console.log('helloworld');}装箱转换:每种基本类型Number、String、Boolean、Symbol在对象中都有对应的类。所谓装箱转换,就是将基本类型转换成对应的对象。是类型转换中非常重要的一个类型。拆箱转换:在JavaScript标准中,规定了ToPrimitive函数,即从对象类型到原始类型的转换。对象到字符串和数字的转换遵循“转换前拆箱”规则。通过拆箱转换,将对象变成基本类型,再从基本类型转换成对应的String或Number。拆箱转换将尝试调用valueOf和toString来获取拆箱的基本类型。如果valueOf和toString都不存在,或者没有返回原始类型,则会引发TypeError。5、12.toString为什么会报错?因为JS中的数字可以有小数点,所以小数点前后的部分可以省略,但不能同时省略。所以一个小数可以表示为'.01'、'12.'、'12.01',当使用12.toString时,12.将被视为一个整体,小数点后的部分被省略。所以如果你想让这个表达式正确执行,你需要添加一个空格('12.toString()')或者再添加一个.('12..toString()')。6.我们需要在JavaScript中写分号吗?结论是可以加分号也可以不加。如果不加分号,有些地方需要注意。注意事项:1)如果下一行的第一个token是五个字符(,[,/,+,-)之一,Javascript不会自动在上一行的末尾添加分号。因此,当下一行第一个token为上述字符时,需要在上一行或行首加分号2)continue、return、break、throw后自动插入分号。所以当return返回一个值的时候,不要把那个值和return放在同一行,否则返回的结果是undefined而不是你期望的值。3)++,--后缀表达式换行开始,行首会自动插入分号。参考链接:知乎--JavaScript语句后要不要加分号?JavaScriptASI机制详解7.为什么在script标签中写export会报错?因为脚本上没有设置type="module"属性。JavaScript中有两种源文件,一种是脚本,一种是ES6模块。import和export可以在模块中使用,但不能在脚本中使用,会报错。现代浏览器可以支持脚本标签来导入模块或脚本。script标签默认的type属性是type="application/javascript",表示script,可以省略。加载一个ES6模块,需要设置type="module"属性,否则浏览器会认为export是写在脚本里的,所以会报错。本文是JavaScript系列的最后一篇,也是重学前端系列的最后一篇。以上内容如有错误,希望大家指出,谢谢。