本已经过原作者 Viduni Wickramarachchi 授权翻译。
你是否经历过JavaScript中的某些值比较没有得到预期结果的情况?
看下面的情况:
即使[]==0结果为真,if[]条件也没有根据结果执行。有没有想过为什么会这样?
本文主要说明这些值比较的工作原理以及影响它们的因素。在深入解释之前,大家要熟悉一个概念:类型转换。
这也称为类型强制。对于不熟悉此概念的人来说,它只是将值从一种数据类型自动转换为另一种数据类型。
看个例子,大家会更清楚明白。
在此示例中,定义的两个变量具有两种类型;字符串和数字。但是,当我们使用 ==(非严格比较)进行比较时,结果为true。原因是当我们使用==比较这两个时,JavaScript 会自动尝试将String类型转换为Number类型以产生结果。这是一种强制转换。
JavaScript中有多种强制类型。
在上述情况下,类型转换没有害处。但是,在许多情况下,类型强制会导致问题。
我们看下面例子。
在这里,JavaScript已将Number类型转换为String。这与相等比较中发生的情况相反。我们预期的结果是450。但是,我们得到了String输出。
现在,我们对类型转换以及为什么要避免使用类型转换有了清晰的了解,让我们看看如何避免类型转换。这是本文最重要的部分。因此,请坐下来,喝咖啡并集中精力
如果你需要对用户输入或任何其他值使用数学运算,则在执行该运算之前,自己进行一次显式转换会更安全。这样,可以避免任何意外行为。
如果需要连接两个数字,则使用模板文字会更安全。特别是不确定值的类型。
也可以使用显式转换来导出相同的结果。
前面我们看到,当使用==时,JavaScript 会执行隐式类型转换,这会导致不一致的结果。因此,在我们的生产代码中使用它是不安全的。
为了得出预期的结果,应该始终使用===进行比较。三等号隐含地表示:
我可以同时了解变量的值和类型
因此,如果将数字和字符串与值进行比较,结果将是false,因为它也会考虑变量的类型。
这是获得预期一致结果的更安全的方法。
在JavaScript中,数据类型有两种变体。
到目前为止,我们已经讨论了原始数据类型的类型转换。我提供的第一个示例涉及非原始数据类型,例如数组。
所有非原始数据类型都有一个名为.toPrimitive()的内置函数。比较非原始值和原始值时,此函数会自动将非原始类型转换为原始类型。在我们看过的第一个示例中,当使用此函数进行非严格比较时,空数组将转换为空字符串。确切地说,用于执行此转换的确切函数是toString()。因此,空数组(将转换为空字符串)等于0。
正如我们前面所看到的,当在if条件中检查空数组时,将执行条件中的行。但是,如果空数组隐式转换为0怎么办?
这是在单独的JavaScript条件下进行的: 真值和虚值 。除了true以外,JavaScript 将大部分有值的视为真值,除了少数值。例如,0,-0,""被视为虚值。由于空数组不被认为是虚值,当在条件中检查它时,它将作为真值执行。(这里不会发生类型转换,空数组保留为数组,这是类型转换不一致的另一个例子。)
JavaScript作为一种松散类型语言,执行隐式类型转换。这会导致不一致和意想不到的结果。因此,我们应该在任何时候都避免这种类型转换。如果不确定值的类型,可以使用typeof检查。检查类型可以让我们更好地理解应该如何进行转换。
~完,我是刷碗智,我要去刷碗了,骨的白~
作者:Viduni Wickramarachchi 译者:前端小智 来源:stackabuse
原文:https://blog.bitc.io/how-to-avoid-javascript-type-conversions-29e1258f37d8
tml+css基础一:html简介和发展史
HTML全称(hypertext markup language)译为超文本标记语言,其译文代表了HTML的含义,它和其他编程语言不同的是,HTML不是一门真正意义上编程语言,而是一种标记语言,通过带有尖角号的标签对文本进行标记,从而实现网页的结构搭建。
1.2、HTML发展史
HTML创始人(蒂姆·伯纳斯-李)蒂姆·伯纳斯-李除了是HTML的创始人,还是w3c组织的主席。
1、HTML1.0 (1991年12月)
1991年万维网(www)在互联网上首次露面,也随之引起了巨大的轰动。
1989年,伯纳斯-李写了一份备忘录,提出建立一个基于互联网的超文本系统。同年和另外一个工程师一起进行联合资金申请,但是这个项目并没有通过。
1991年底的时候,伯纳斯-李公开了一份“HTML Tag”的文档,里面描述了组成HTML初始版本的18个元素
2、HTML2.0(1995年11月)
HTML 2.0是HTML语言的扩展。
与原始版本的HTML不同,HTML 2.0被创建为Web标准,规定了常见的网页结构
3、HTML3.2(1996年1月)
惨淡的"第一次浏览器大战时期(Netspace Vs IE)",两大巨头不断推出重大举措试图控制整个领域。
网页开发者是这场战争中的焦点。商业战争就像军备竞赛,各家公司为了保持领先,招兵买马。各家都有各家的规则。
那时候,你不得不写两份不同的网页,一个用于网景的浏览器,另一个用于微软的浏览器
4、HTML4(1997年12月)
浏览器大战接近尾声,W3C(世界万维网联盟)成立,他们打算通过制定统一的HTML标准,使整个产业能有序的发展。
他们计划用两种语言分离出HTML的表达式(HTML 4.0)和结构(CSS),并且说服浏览器厂商接受这些标准
这次发布提供了规范的三种变体:
Strict,严格版本;
Transitional,过渡版本;
Frameset,iframe框架集;
HTML4.0 采纳了许多浏览器特定的元素类型及属性,但是同时也把 Netscape 的视觉化标记标记为过时的寻求淘汰; 赞成使用样式表; 同时在1998年4月对HTML4.0进行了微小的修订,没有增加版本号HTML5.0
5、HTML4.01(1999年12月)
像 HTML4.0 一样提供了三种变体,并且他的最终错误修订版在2001年的5月12日发布
6、XHTML 1.0(2000年1月)
各大浏览器厂商纷纷接受W3C标准的时候,新技术出现了。
HTML和另一种语言XML融合,XHTML(可拓展的超文本标记语言)就此诞生。
它继承了HTML的通用型和浏览器的兼容性,继承了XML的严密性和可拓展性
7、HTML5(2014 年 10 月)
HTML5是HTML最新的修订版本,由W3C制定,目标是取代1999年所制定的HTML 4.01和XHTML 1.0标准
我们现在使用的是html5版本,因为由于新兴框架的出现和浏览器兼容性的提升,让我们选择了html5。
this字面意思是当前,当前执行代码的环境对象或者是上下文。代表着当前方法执行的环境上下文,那么何为环境上下文,通俗的说,谁调用了函数,谁就是这个函数的环境上下文。
在js中,this只有两种指向,一种是指向当前的封闭作用域,或者是指向当前作用域的外层,this的最顶层就是window对象。
关于this必须要了解的是严格模式,严格模式是js里面的一个子集,是具有限制性JavaScript变体,严格模式也是js的一种,但是加了一些限制。
比如:
进入"严格模式"的标志:"use strict";
// 为整个脚本开启严格模式 "use strict"; var v = "Hi! I'm a strict mode script!"; // 为函数开启严格模式 function strict() { 'use strict'; function nested() { return "And so am I!"; } return "Hi! I'm a strict mode function! " + nested(); }
在全局环境下,无论是否在严格模式下,在全局执行环境下(任何函数体外部)this指向全局对象。也就是说在全局执行环境,这个this永远指向全局对象,这个全局对象在浏览器中就是window。
//浏览器环境 var name = 'Eric'; console.log(window.name === this.name); /* true */ console.log(window === this); /* true */
在函数体内部,this的值取决于函数被调用的方式。函数被调用的方式有很多种:
简单调用,也就是说没有添加任何额外的操作,没有添加一个this的绑定或者是改变。
简单调用分为严格模式与非严格模式。
// 浏览器环境 function simple(){ return this; } console.log(simple() === window); // true
// 浏览器环境 function simple2(){ "use strict"; return this; } simple2() === undefined; // true window.simple2() === window; // true
this传递,在js中this绑定有两种:
// 浏览器环境 var object = { name: 'Eric' }; var name = 'Iven'; function getName(arg) { return this.name; } getName(); /* Iven */ getName.call(object); /* Eric */ getName.apply(object); /* Eric */
name = 'Davy'; function bindThis(){ return this.name; } var getName1 = bindThis.bind({ name: "Eric" }); console.log(getName1()); /* Eric */ var getName2 = getName1.bind({ name: "Iven" }); console.log(getName2()); /* Eric */
箭头函数在执行的时候会形成一个封闭的作用域,this与封闭作用域的this保持一致,call/apply/bind都将会被忽略。
// 浏览器环境 var globalThis = this; var arrowsFunction = () => this; console.log(arrowsFunction() === globalObject); /* true */
作为对象的方法被调用(有一个靠近原则):在对象里面定义了一个函数,然后通过对象去调用这个函数。
// 浏览器环境 var object = { name: 'Eric', getName: function() { return this.name; } }; console.log(object.getName()); /* Eric */ function getName2() { return this.name; } object.getName = getName2; console.log(object.getName()); /* Eric */ object.object = { getName: getName2, name: 'Iven' }; console.log(object.object.getName()); /* Iven */
setInterval()方法用于在指定的毫秒数后调用函数或计算表达式。
语法:setTimeout(code,millisec),参数code必需,要调用的函数后执行的JavaScript代码串;millisec必需,在执行代码前等待的毫秒数。
注意:setTimeout()只执行code一次,如果需要多次调用,请使用setInterval()或者让code自身再次调用setTimeout(),也就是利用递归。
setInterval()方法可按照指定的周期来调用函数或计算表达式。它会不停地调用函数,指导clearInterval()被调用或者窗口被关闭。由setInterval()返回的ID值可以用作clearInterval()方法的参数。
*请认真填写需求信息,我们会在24小时内与您取得联系。