zoukankan      html  css  js  c++  java
  • javascript 的比较运算与逻辑运算

    1、在 == 运算中,undefined == null  ,除此之外,这2 个数据不与任何其他数据相等
    2、string 、 number  、与 boolean之间比较,如果2个数值的类型不同,可以把非number型转换成number型 (like Number(),not parseFloat()),再进行比较,(大小比较运算确实是这样,但等于和不等于比较不是,但是对于 js 的标量(这里“标量”的不准确且不负责提法是指 boolean 、string 、number ), 这样做也是没错的,把 true 作为1,false 作为 0,剩下另一个就是字符串了),例如 , "true" == true ,  无论将 "true" 转 boolean 还是将 true 转 string ,都得不到正确结果, 将他们转换为 number 比较就能得到正确结果。


    3、对象型数据(String、 Number、Boolean、object、Array、function 等等)与string 、number  、boolean类型比较,会使 用valueOf()、toString() 方法的返回值参与比较,对象与对象比较,只要类型不同就为false,不会调用valueOf() 和 toString(),事实上,任何对象型数据都只等于自己.
    4、NaN属于number型,不与任何数据相等,包括他自身, !NaN == true , isNaN(Number(undefined)) == true

    5、Infinity 首先属于number型,然后,Infinity 只等于Infinity 
    6、 注意if语句中的表达式的位置特殊性,不要把比较运算与逻辑运算(||、&&)混为一谈,逻辑运算也不要与布尔运算(运算元前面 加 ! )混为一谈,逻辑元算总是返回一个运算元,比较运算和布尔运算总是返回true/false. if 语句的条件表达式隐含一个布尔运算的效果: 将表达式运算结果 result 执行 !!result 得到 true/false .

    7、逻辑运算中,判断为 false 的数据有:false、null、undefined、空字符串、0、NaN,其余数据都是true,任何对象型数据都是true,包括Boolean对象自身。逻辑运算中, && 优先于 ||,试比较:

    3 || 0  &&  2 ; //3 ,即 3||(0&&2)
    (3 || 0 ) &&  2 ; //2
    
     

    8、===运算中,先比较类型,后比较数值

    9、在switch-case中,case 参数是区分类型的

    10、 在大于、小于(>、>=、>==、<、<=、<==)比较运算中,两边的运算元都转换成数字,undefined 与任何其他数据(包括 null)进行大于、小于比较都是 false,( Number(undefined) is NaN ),而 null 则被转换成数字 0 后进行比较(在ECMASCRIPT规范中,不同类型的标量进行大于、小于比较时,是转数字比较的,只有数字,大小的含义才有存在的价值 ,字符串之间的比较也是进行 unicode 码的比较),因此会有:

    null<=0; //true
    
    null>=0; //true
    
    null>0; //false
    
    null<0;//false
    
    null==0;//false
    
     
    
    undefined==null  //true
    
    undefined<=null  //false
    
    undefined>=null  //false

    再看数组:

    [1]==[1]; //false 两个不同的对象
    [1]>=[1]; //true, 转换成数字后比较 Number([1].valueOf().toString())==1

    更权威的文档看这里(ECMASCRIPT):

    http://bclary.com/2004/11/07/#a-11.8.5

    undefined 不是关键字,在非全局环境下,undefined 可以被重定义 

     //test1
      var undefined = 1;
      console.log('test1',undefined,typeof undefined);  //全局环境下, undefined 不会被修改
    
      //test2
        (function(){
           undefined = 2; //全局的undefined 不会被修改
           console.log('test2',undefined,typeof undefined);
        })();
    
          //test3
        (function(){
           var undefined = 3; //undefined 被重定义
           console.log('test3',undefined,typeof undefined);
        })();
    
        //test4
        (function(x,undefined) {    //该闭包内 undefined 被重定义了      
            console.log('test4',undefined,typeof undefined,arguments)
            console.log(undefined*2) // 8          
        }('a',4))

     

    关于类型转换:

    在对象型数据参与比较运算和算术运算(+、-、*、% 等)时,使用对象型数据的valueOf()方法的返回值参与运算(Date 对象看场景,有点不太一样),标量对象和时间对象的 valueOf() 返回值都是标量,其他对象的返回值都是 object/function 型,如果 valueOf() 得不到标量,则继续调用 toString() 方法,使用 toString() 的返回值参与运算,如果这两个方法返回的都不是标量(或 undefined、null),程序将报错

    日期对象在这里跟其他对象有点不同,日期对象参与的 “+” 和 "==" 运算将直接理解为字符串,会跳过valueOf() 直接调用toString返回string,如果得不到标量则继续尝试 valueOf(),而 Date 对象参与乘法运算仍是调用valueOf返回数字参与运算,这可能是从日期的实用意义来考虑的,日期数据主要是用于阅读。

    在界面输出字符串时会直接调用 toString 方法,比如 alert(x), document.write(x),如果 toString() 返回的不是标量,则尝试 valueOf() ,仍然得不到标量则报错

    对于 parseInt([1]) 这样的情况, 参数位置的数组将直接调用 toString() 方法,这是由于 parseInt() 函数(包括 parseFloat() 和上述的界面输出函数)的实现方式使然,这些函数期望接收到的参数类型是string,并非参数的数据类型自身的自动转换导致。

    一些测试:

    //Array 
    
    var _arrToString = Array.prototype.toString;
    
    var _arrVal = Array.prototype.valueOf;
    
    Array.prototype.toString=function(){
    
    console.log("Array.toString is called");
    
    return _arrToString.call(this);
    
    };
    
    
    Array.prototype.valueOf=function(){
    
    console.log("Array.valueOf is called");
    
    return _arrVal.call(this);
    
    };
    
    [1]+2 //Array.valueOf is called   ,  Array.toString is called
    parseInt([1]) //parseInt 期望接收 string 型参数,直接调用了 Array.toString
    Number([1]) //valueof toString 先后被调用
    
    //Boolean 
    var _arrToString = Boolean.prototype.toString;
    
    var _arrVal = Boolean.prototype.valueOf;
    
    Boolean.prototype.toString=function(){
    
    console.log("Boolean.toString is called");
    
    return _arrToString.call(this);
    
    };
    
    
    Boolean.prototype.valueOf=function(){
    
    console.log("Boolean.valueOf is called");
    
    return _arrVal.call(this);
    
    };
    
    
    1+new Boolean(true); //Boolean.valueOf is called
    
    
    
    //object
    
    var tostr = Object.prototype.toString;
    
    var valof = Object.prototype.valueOf;
    
    Object.prototype.toString = function(){ 
    
    console.log('Object.toString iscalled'); 
    
    return tostr.call(this); 
    
    }
    
    
    Object.prototype.valueOf = function(){ 
    
    console.log('Object.valueOf is called');
    
     return valof.call(this); 
    
    }
    ({})== 1; //  valueOf toString 先后被调用
    ({})== ({}); // 这里 valueOf 和 toString 未被调用
    
    
    //Date
    var valueof = Date.prototype.valueOf;
    var toString = Date.prototype.toString;
    Date.prototype.valueOf = function(){
        console.log('valueof is called');
        return valueof.call(this);
     }
     
    Date.prototype.toString = function(){
        console.log('toString is called');
        return toString.call(this);
     }
     
     new Date()+1; //toString is called
     new Date()*1; //valueOf is called
     new Date()==1;//toString is called
     new Date()>=1;//valueOf is called
     parseInt( new Date()); //toString is called
     Number( new Date()); //valueOf is called

     // toString 的调用

    var tostr = Array.prototype.toString;
    var valof = Array.prototype.valueOf;
    Array.prototype.toString = function(){ console.log('Array.toString iscalled'); return tostr.call(this); }
    Array.prototype.valueOf = function(){ console.log('Array.valueOf is called'); return valof.call(this); }
    
    var arr = [2];
    alert(arr); //Array.toString iscalled
    
    var x = arr +1; //Array.valueOf is called ,Array.toString is called 

    由于 Number(undefined)===NaN , Number(null)===0 ,因此 undefined 参与的数字运算将得到NaN,而null将作为数字0参与运算。

    前 ++ 和后++ 运算属于单目运算,运算元会转换成number型再参与运算: 'a'++ 和 ++'a'  都会得到NaN,因为Number('a')=NaN.

     当+作为单目运算符时,表示“取正数”,如 alert(+'a'); //NaN ,alert(typeof(+'1')); //number

    Number() 函数将8进制格式的字符串按十进制处理,去掉前导的0

            alert(012==10); //true
            alert('012'==10); //false
            alert(012=='012');//false
             
    
            alert(09==9); //true ,不符合8进制数,作为 十进制数处理
    
            alert(012==10); //true 符合8进制数
    
    
            alert(Number(012));//10 ,(012).toString(10) 得 '10'
            alert(Number('012'));//12,没有按八进制处理而是去掉0,注意区别 parseInt('012') 在firefox 和IE8 中得到 10(最新版本的 firefox 也已经返回 12),但在 IE9、IE10 和chrome 中得到12
    
            alert(0x12==18);//true
            alert('0x12'==18);//true
            alert(0x12=='0x12');//true
            alert('0x12'=='18');//false ,字符串的比较,没有发生数据类型转换
    
    
            alert(Number(0x12));//18 
            alert(Number('0x12'));//18

    parseInt 将字符串转换成十进制整数时,可以接受2 个参数,第二个参数用于申明传入的字符串的进制

    parseInt('abc',16); // 2748 ,将16进制数 abc 转换成10进制

    对应的,number 对象的toString 方法也可以接受1个参数表示按哪一种进制转换成字符串:

    (2748).toString(16); //abc

    Object 与标量 Number 、String 、Boolean及 Date 的构造器不同,

    如果 obj 是对象,则有

    obj === new Object(obj) === Object(obj) 

    Number 、String 、Boolean、 Date 构造器则每次 new 都返回一个新的对象,如果不使用new,则返回新建对象的 valueOf 的值

     
    var x = new Number();
    
    x=== new Number(x) //false
    
    x=== new Object(x) //true
    
     
    //=======test=========
    var x =  new Number(1)
    x=== new Number(x) //false
    x=== new Object(x) //true
    x===  Object(x) //true
     
    
    x.constructor //function Number() { [native code] }
    
    Object(x).constructor //function Number() { [native code] }
    (new Object(x)).constructor //function Number() { [native code] }
    
    typeof(new Number("123")); //object
    typeof(Number("123")); //number, not object
  • 相关阅读:
    Java日历表
    递归实现文件的大小计算
    将机器学习的个性化推荐与社会化机制相结合
    设计模式——抽象工厂模式
    从mysql到nosql
    设计模式——Adapter模式(变压器)
    Java 正则匹配
    对象集合转换为datatable
    sql1
    Oracle Index 相關知識
  • 原文地址:https://www.cnblogs.com/ecalf/p/2793921.html
Copyright © 2011-2022 走看看