javascript 中 !~ 什么意思

快过年放假了,也终于闲下来了。每天游览于各种技术文章中,这种状态好极了。
下午看篇关于js的文章,其中有如下这么一段引起了我的注意。

(function () {
    var names = [];
    return function (name) {
        addName(name);
    }
    function addName(name) {
        if (!~names.indexOf(name))//如果存在则不添加
            names.push(name);
        console.log(names);// ["linkFly"]
    }
}())(‘linkFly‘);

if (!~names.indexOf(name)) 中的操作符"!~" 什么意思,不理解,先从~入手。

测试可以得出结果值有这个的规律 -(X+1)

搜索一番,有的文章只丢一句:按二进制位取反

从字面意思,这里用八位二进制表示:3=00000011,那~3=11111100,套上面公式不对呀。
上面解释还是太过抽象不具体。其实这涉及到原码、反码、补码的知识。

原码
原码表示法最高位为符号位,该位为0表示正数,1表示负数。其余位表示数的绝对值。
反码
对于一个带符号的数来说,正数的反码与其原码相同;负数的反码为其原码除符号位以外的各位按位取反。反码常用来做求补码过程中的中间形式。
补码
正数的补码与其原码和反码相同;负数的补码是对它的原码除符号位以外各位取反,并在末位加1而得到,即为该数的补码加1。计算机内的数一般以补码形式表示。在补码中用(-128)D代替了(-0)D,注意:(-128)D没有相对应的原码和反码,(-128)D = (1000,0000)B。
求补运算
求补运算不考虑符号位,对它的原码各位取反,并在末位加1而得到。对一个数进行求补运算所得的是该数相反数的补码。

拿作者文章例子,理解下

~是按位取反的意思,取反就是如果是00111,则变为11000 (按位取反)

57的二进制表示为(1个字节):00111001
按位取反后(~57)的二进制: 11000110 此表示为十进制:-70
这是一个负数,是有符号的数,负数在计算机里要用其补码来表示:补码=符号位以后按位取反再加1.
所以-70(11000110)符号位以后按位取反后为(10111001) 再加1 则为(10111010)
换成十进制为:-58
因此~57=-58

至此算是终于搞明白了。虽然总结的公式能快速得出结果,但不能解释为什么,作为技术人我们喜欢钻研,深入细节。

感叹时间:

正如作者的标题中所说最基本也最容易忽略的东西,混了几年连基本都没了,被人问到得贻笑大方。
基础是一切上层的基石,潜心修道,路漫漫。

参考文章:
http://blog.csdn.net/zhongjling/article/details/8004103
http://www.cnblogs.com/acheng99/archive/2009/09/02/1559037.html

时间: 2024-08-03 17:14:58

javascript 中 !~ 什么意思的相关文章

实现一个函数clone,使JavaScript中的5种主要的数据类型(包括Number、String、Object、Array、Boolean)进行值复制

实现一个函数clone,可以对JavaScript中的5种主要的数据类型(包括Number.String.Object.Array.Boolean)进行值复制. 1 /** 对象克隆 2 * 支持基本数据类型及对象 3 * 递归方法 */ 4 function clone(obj) { 5 var o; 6 switch (typeof obj) { 7 case "undefined": 8 break; 9 case "string": o = obj + &q

javascript中的原始值和复杂值

前面的话 javascript的数据类型可以分为两种:原始类型(基本类型或者简单类型)和引用类型. 原始类型:Undefined,Null,Boolean,Number,String五种: 引用类型:Object,Array,Function: 与此相对应的,它们的值分别被称为原始值和复杂值. 特性 原始值 原始值是表示javascript中可用的数据或信息的最底层的形式或者最简单的形式.原始类型的值被称为原始值,因为它们的值是不可被细化的.也就是说,数字是数字,字符串是字符串,布尔值是true

【JS】JavaScript中的执行环境与作用域

JavaScript中的执行环境定义了变量或函数有权访问的数据(每个函数都有自己的执行环境),全局执行环境是最外围的执行环境,在浏览器中,全局执行环境就是window对象,所以所有的全局变量和函数都是作为window对象的属性和方法创建的.当某一个执行环境中所有代码执行完成后,该环境就被销毁,保存在其中的变量和函数也将被销毁,全局执行环境在关闭网页或浏览器时才被销毁. 当代码在一个环境中执行时,会创建变量对象的一个作用域链(保证对执行环境有权访问的变量和函数的有序访问),如果环境是函数,将其活动

JavaScript中的构造函数

function Accom(){};    //创建一个构造函数 //创建两个对象 var house=new Accom(); var apartment=new Accom(); 通过构造函数创建的对象有一个属性constructor,这个属性指向创建该对象时所用的Javascript构造函数. house.constructor===Accom;  或者   house instanceof Accom;     //true JavaScript中的每个构造函数都有一个prototyp

【转】十个JavaScript中易犯的小错误,你中了几枪?

在今天,JavaScript已经成为了网页编辑的核心.尤其是过去的几年,互联网见证了在SPA开发.图形处理.交互等方面大量JS库的出现. 如果初次打交道,很多人会觉得js很简单.确实,对于很多有经验的工程师,或者甚至是初学者而言,实现基本的js功能几乎毫无障碍.但是JS的真实功能却比很多人想象的要更加多样.复杂.JavaScript的许多细节规定会让你的网页出现很多意想不到的bug,搞懂这些bug,对于成为一位有经验的JS开发者很重要. 常见错误一:对于this关键词的不正确引用 我曾经听一位喜

JavaScript中Function的拓展

Function 是什么东西,就是JavaScript中的顶级类,系统级别的类.我们平时写的函数方法例如下. function Animal() { } Animal就是Function的实例,但是在我们的逻辑中 Animal是类,是自定义类. Function是类,Animal是类也是实例,Animal是Function的实例,Animal是自定义类.这点大家一定要搞清楚. 我们在顶级类上定义一个method的方法,用于进行键值对的方式进行方法链式的设定, Function.prototype

浅谈JavaScript中继承的实现

  谈到js中的面向对象编程,都有一个共同点,选择原型属性还是构造函数,两者各有利弊,而就片面的从js的对象创建以及继承的实现两个方面来说,官方所推荐的是两个相结合,各尽其责,各取其长,在前面的例子中,我已就在JavaScript中对象创建的方法做了一些总结,下面就其继承来道说一二:   1:原型链继承: 每一个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象内部的指针(默认的原型,所有默认类型都继承了Object,而这个继承也是用过原型链实现) fu

理清javascript中prototype、__proto__、Object、Function的关系,更好地理解原型继承

本文参考了http://www.blogjava.net/heavensay/archive/2013/10/20/405440.html这篇文章,对其内容作了个简单总结,形成了几条简单的结论,让读者更容易记住prototype.__proto__.Object.Function之间的关系. 结论1:Object.prototype只是一个普通对象,它是js原型链的最顶端. (typeof Object.prototype) === object;//true Object.prototype.

javascript中的立即执行函数(function(){…})()

javascript中的立即执行函数(function(){…})() 深入理解javascript中的立即执行函数,立即执行函数也叫立即调用函数,通常它的写法是用(function(){…})()包住业务代码,使用jquery时比较常见. ( function(){…} )()和( function (){…} () )是两种javascript立即执行函数的常见写法,最初我以为是一个括号包裹匿名函数,再在后面加个括号调用函数,最后达到函数定义后立即执行的目的,后来发现加括号的原因并非如此.要

javascript中的栈、队列。

                       javascript中的栈.队列 栈方法     栈是一种LIFO(后进先出)的数据结构,在js中实现只需用到2个函数 push()  接受参数并将其放置数组尾,并返回修改后的数组长度. pop()  移除数组尾的最后一项,并返回移除项的值. 事例: var colors = new Array();var count = colors.push("red","green"); count = colors.push(&