Advertisement

JS中~和~~运算符的含义解析

  •  5星
  •     浏览量: 0
  •     大小:None
  •      文件类型:PDF


简介:
本文详细解释了JavaScript中的~(按位非)和~~(双重按位非)运算符的工作原理及其应用场景,帮助开发者更好地理解与运用。 在JavaScript编程语言中,位运算符主要用于处理整数数据类型的操作;然而,在涉及到浮点数进行位操作时,JS会自动将这些浮点数值转换为32位二进制补码表示形式的整型以执行相应的计算任务。 首先我们来看按位非(~)运算符的应用。当应用该运算至一个数字值时,它会对这个数字在计算机内部存储的二进制代码进行逐比特取反操作(即1变为0,0变1)。如果输入的是非数值类型的数据,则JS会尝试将其转换为32位整数;若此过程失败导致结果是NaN,那么~ NaN的结果就是-1。对于负数值,在执行按位非运算后将得到比原数字小一的正整数。 例如, 对于`(-2.9)`这个数值,首先会被转化为 `-3`(这里取的是最接近的向下取整),然后进行按位非操作,结果是 `0b00000000 0000111`, 即十进制中的数字 `2`. 对于正数来说, 按位非运算则会得到比原数值大一的负数。例如`~2.6`首先转换为整数2,执行按位非后结果是二进制形式的-3。 接下来介绍双按位非(~~)操作符的应用场景:这种连续两次应用按位非的操作通常用来将各种类型的数据强制转化为整型数值,并且可以实现向上或向下取整的效果。对于正数而言, `~~testData` 相当于执行了 `Math.floor(testData)`,即去除了浮点数的小数部分并进行下舍操作;而对于负数,则相当于进行了上取整的操作。 例如:`~~2.1` 会先变成 `-1`, 然后再应用按位非变为 `0`. 而对于 `~~(-2.9)`, 则是先将它转化为 `~ -3 = 2`, 再次进行按位非操作后结果不变,仍然是 `2`. 在某些情况下, 如jQuery代码中可能使用`~this.className.indexOf(str)`来判断一个字符串是否存在于另一个字符串内。这里indexOf()函数返回的是子串位置的索引值;当找不到时返回-1. 使用双按位非可以将这个索引值转换为布尔值,从而快速完成包含性检查。 总的来说, 在JavaScript中利用`~`和 `~~` 运算符不仅可以进行数值类型的位运算操作,还能在特定场景下帮助简化浮点数的处理逻辑。理解这些运算符的工作机制对于编写高效的代码至关重要。

全部评论 (0)

还没有任何评论哟~
客服
客服
  • JS~~~
    优质
    本文详细解释了JavaScript中的~(按位非)和~~(双重按位非)运算符的工作原理及其应用场景,帮助开发者更好地理解与运用。 在JavaScript编程语言中,位运算符主要用于处理整数数据类型的操作;然而,在涉及到浮点数进行位操作时,JS会自动将这些浮点数值转换为32位二进制补码表示形式的整型以执行相应的计算任务。 首先我们来看按位非(~)运算符的应用。当应用该运算至一个数字值时,它会对这个数字在计算机内部存储的二进制代码进行逐比特取反操作(即1变为0,0变1)。如果输入的是非数值类型的数据,则JS会尝试将其转换为32位整数;若此过程失败导致结果是NaN,那么~ NaN的结果就是-1。对于负数值,在执行按位非运算后将得到比原数字小一的正整数。 例如, 对于`(-2.9)`这个数值,首先会被转化为 `-3`(这里取的是最接近的向下取整),然后进行按位非操作,结果是 `0b00000000 0000111`, 即十进制中的数字 `2`. 对于正数来说, 按位非运算则会得到比原数值大一的负数。例如`~2.6`首先转换为整数2,执行按位非后结果是二进制形式的-3。 接下来介绍双按位非(~~)操作符的应用场景:这种连续两次应用按位非的操作通常用来将各种类型的数据强制转化为整型数值,并且可以实现向上或向下取整的效果。对于正数而言, `~~testData` 相当于执行了 `Math.floor(testData)`,即去除了浮点数的小数部分并进行下舍操作;而对于负数,则相当于进行了上取整的操作。 例如:`~~2.1` 会先变成 `-1`, 然后再应用按位非变为 `0`. 而对于 `~~(-2.9)`, 则是先将它转化为 `~ -3 = 2`, 再次进行按位非操作后结果不变,仍然是 `2`. 在某些情况下, 如jQuery代码中可能使用`~this.className.indexOf(str)`来判断一个字符串是否存在于另一个字符串内。这里indexOf()函数返回的是子串位置的索引值;当找不到时返回-1. 使用双按位非可以将这个索引值转换为布尔值,从而快速完成包含性检查。 总的来说, 在JavaScript中利用`~`和 `~~` 运算符不仅可以进行数值类型的位运算操作,还能在特定场景下帮助简化浮点数的处理逻辑。理解这些运算符的工作机制对于编写高效的代码至关重要。
  • C语言宏定###
    优质
    本文介绍了C语言中宏定义的重要操作符#和##的功能与用法,帮助读者掌握预处理器指令的应用技巧。 本段落主要介绍了C语言中#与##运算符的用法及区别。
  • C++单目双目重载方法
    优质
    本文详细解析了在C++编程语言中如何实现单目运算符与双目运算符的自定义重载,探讨其语法特点及应用场景,帮助读者掌握灵活运用运算符增强代码可读性的技巧。 C++中的单目运算符只有一个操作数,例如!a、-b、&c、*p以及最常用的++i和–i等。重载单目运算符的方法与双目运算符类似,但由于单目运算符只涉及一个操作数,因此其对应的运算符重载函数也只需要一个参数;如果作为成员函数,则可以省略这个参数。 以自增运算符++为例来介绍如何进行单目运算符的重载。假设有一个名为Time的类,它包含两个数据成员minute(分钟)和sec(秒),用该类模拟一块秒表的功能:每当时间增加一秒时,如果达到60秒,则进位到下一分钟,并将当前秒钟重新设置为零。 以下是实现这一功能的一个示例代码: ```cpp #include using namespace std; class Time { public: int minute; int sec; // 分钟和秒 Time(int m = 0, int s = 0) : minute(m), sec(s) {} // 构造函数,初始化分钟和秒数 void operator++(); // 前置递增运算符的声明 }; void Time::operator++() { ++sec; // 秒增加一 if (sec == 60) { minute++; sec = 0; } } int main() { Time t(1,59); // 创建一个Time对象,初始值为1分59秒 cout << 当前时间: << t.minute << 分钟 << t.sec << 秒\n; ++t; // 使用前置递增运算符增加一秒 cout << 更新后的时间: << t.minute << 分钟 << t.sec << 秒\n; return 0; } ``` 此代码段展示了如何定义一个类Time,并在其中重载了++操作符,以实现模拟时间的自动进位。
  • C++const_cast与reinterpret_cast用法
    优质
    本文深入解析了C++编程语言中const_cast和reinterpret_cast两种类型转换运算符的具体使用方法及其应用场景。 C++中的类型转换运算符是编程的重要特性之一,它允许程序员显式地改变对象的类型。在这些操作符里,const_cast和reinterpret_cast尤其重要,在进行特定类型的转换中扮演了关键角色。 首先讨论的是const_cast运算符,主要用于去除指针或引用上的`const`, `volatile` 和 `__unaligned` 限定词。实际上编程时,我们有时会遇到需要修改原本设计为只读的数据的情况;例如想通过非`const`成员函数来操作对象的属性。这时可以使用 const_cast 来忽略编译器对数据类型的限制,从而直接进行修改。然而需要注意的是, 这种转换仅适用于指针或引用类型,并且不能用于临时变量或者顶层常量限定的对象上。此外,在利用const_cast解除`const`修饰后要确保有权限去改变该对象的数据状态,否则可能会导致未定义的行为。 使用 const_cast 的语法如下: ``` const_cast(expression) ``` 其中 `type-id` 是目标类型而 `expression` 则是需要进行转换的表达式。例如,对于一个指向只读数据类型的指针,我们可以通过以下方式去除其限定符并修改对象的数据成员: ```cpp CCTest* constC = new CCTest; ...后续代码 CCTest* c = const_cast(constC); c->setNumber(5); // 成功调用非常量成员函数来修改数据。 ``` 接下来介绍reinterpret_cast,该运算符提供了一种底层的类型转换方式。这种操作通常会基于具体的硬件架构和编译器有所不同,并且具有较高的风险性。它主要用于指针之间的相互转换或整数与指针类型的互相改变。 例如: ```cpp char* c = new char[10]; unsigned short hashVal = reinterpret_cast(c); ``` 这里,我们将一个`char`类型指针转换成了一个无符号短型数字。由于不同系统下这两种数据类型的大小可能不一样,所以这种操作可能会导致未定义的行为。 使用reinterpret_cast的语法如下: ``` reinterpret_cast(expression) ``` 其中 `type-id` 是目标类型而 `expression` 则是需要进行转换的对象或值。在应用此运算符时需格外谨慎,因为它并不改变数据的实际表示形式而是仅仅改变了对原有二进制数据的理解方式。 滥用这种类型的强制性类型转换可能会导致代码的不可移植性和程序崩溃的风险增加。尽管它允许执行一些复杂和底层的数据操作,但始终应以审慎的态度来使用。例如将一个类指针强行转换为另一个不相关的类指针是不明智且危险的行为(如尝试把`One_class*`转成 `Unrelated_class*`)。 在实现哈希函数时的一个典型示例中可以利用这种类型转换,即将地址映射到唯一的索引: ```cpp unsigned short Hash(void* p) { unsigned int val = reinterpret_cast(p); return (unsigned short)(val ^ (val >> 16)); } ``` 在这个例子中,我们首先将一个`void`指针转为无符号整数类型,然后通过对地址值进行按位移位和异或运算来生成唯一的索引。 在使用这些强制性转换操作符时应遵循C++编程的核心原则:尽量避免不必要的强制型别转换除非其他方案不可行或者确实需要。同时,在大多数情况下应该优先考虑利用模板和类型特性实现安全的自动类型推断,而不是依赖于传统的强制转换运算符。
  • 深入SQL EXISTS
    优质
    本文详细探讨了SQL中的EXISTS运算符,解释其工作原理、使用场景,并通过实例展示了如何利用它来优化查询效率。 本段落主要介绍了SQL EXISTS运算符的相关资料,并详细讲解了其语法与用法。通过实例帮助读者更好地理解和学习这一主题。有兴趣的读者可以参考此文进行深入了解。
  • 深入SQL EXISTS
    优质
    本文将详细介绍SQL中的EXISTS运算符,包括其工作原理、使用场景及与其它查询语句结合的方式,帮助读者掌握高效的数据检索技巧。 SQL EXISTS 运算符是查询中的一个重要条件,用于检查子查询是否至少返回一行数据。如果子查询有记录存在,则EXISTS运算符会返回True;否则返回False。这种操作通常在联合查询和包含多个表的复杂查询中使用。 其基本语法结构如下: ```sql SELECT column_name(s) FROM table_name WHERE EXISTS (SELECT column_name FROM table_name WHERE condition); ``` 这里,主查询中的FROM子句指定了要检查的数据表,并通过WHERE子句后的EXISTS关键字和随后的子查询来判断是否存在满足特定条件的数据。 例如,在一个名为RUNOOB的示例数据库中,“Websites” 表存储了网站的基本信息(id、name、url等),而“access_log”记录了访问次数。假设我们想找出哪些网站有超过200次访问,可以使用以下SQL语句: ```sql SELECT Websites.name, Websites.url FROM Websites WHERE EXISTS (SELECT count FROM access_log WHERE Websites.id = access_log.site_id AND count > 200); ``` 这将返回所有在“access_log”表中有超过200次访问记录的网站名称和URL。 同样,EXISTS也可以与NOT关键字结合使用,以找出不符合特定条件的数据。例如: ```sql SELECT Websites.name, Websites.url FROM Websites WHERE NOT EXISTS (SELECT count FROM access_log WHERE Websites.id = access_log.site_id AND count > 200); ``` 这将返回所有在“access_log”表中没有超过200次访问记录的网站名称和URL。 在实际应用中,EXISTS和NOT EXISTS可以优化查询性能,特别是在处理大型数据集时。相比使用IN、NOT IN或者JOIN操作,在某些情况下,EXISTS可能更高效,因为它找到第一条匹配记录后就会停止执行,而不需要继续遍历整个子查询的结果集。 因此,理解并正确应用SQL EXISTS运算符对于数据库开发者和管理员来说非常重要。这不仅能帮助编写出高效的查询语句,还能提高处理大量数据时的响应速度。
  • 串四则
    优质
    字符串四则运算解析器是一款能够将包含加、减、乘、除等操作符的数学表达式解析并计算结果的工具。它支持复杂表达式的求值,并保证运算的准确性与效率,广泛应用于计算器软件及编程环境中的算术处理。 四则运算解析器可以用来解析字符串形式的数学表达式。这个项目代码简洁明了,非常适合编程新手学习使用。
  • JSHTML字示例代码
    优质
    本文章提供了一个在JavaScript环境中解析HTML字符串的具体实例和代码实现。通过这段教程,读者能够掌握如何将HTML字符串转换为可操作的DOM对象,以便进行进一步的数据处理或页面渲染。 在JavaScript中直接添加HTML语句时,JS会将HTML字符串解析成相应的HTML元素,并在前端进行显示。例如: ```javascript var el = document.createElement(div); el.innerHTML = titleTesttest01test02test03; ``` 这段代码创建了一个包含标题和三个链接的HTML结构。
  • C#&&、||与&、|区别详
    优质
    本文深入解析了C#编程语言中逻辑运算符(&&, ||)和位运算符(&, |)的区别及其应用场景。通过对比分析帮助开发者理解何时使用何种操作符以提升代码效率及可读性。 本段落详细介绍了C#中的(&&, ||)与(&, |)的区别,并通过示例代码进行了讲解,具有一定的参考价值,适合学习或工作中使用。希望对大家有所帮助。
  • VC++与计表达式字串(四则及三角、反三角函数)
    优质
    本文章介绍了如何使用VC++解析和计算包含四则运算以及三角、反三角函数的复杂表达式字符串的方法,适合需要进行数学公式处理的开发者参考。 输入的表达式字符串不仅包含“+-*/()”等四则运算符号,还可以包括“sin, cos...”等三角函数及反三角函数。通过VC++编写代码可以非常简洁地实现这一功能,另辟蹊径的方式令人眼界大开!