zoukankan      html  css  js  c++  java
  • JavaScript-数据类型

    一、简介

    • 数值:整数和小数
    • 字符串:文本
    • 布尔值:true和false
    • undefined:未定义或不存在
    • null:空值
    • 对象:各种值组成的集合

    二、null和undefined

    /*
    null:转成数值是0
    undefined转换数值是NAN
    */
    
    // 变量声明了,但没有赋值
    var i;
    i // undefined
    
    // 调用函数时,应该提供的参数没有提供,该参数等于 undefined
    function f(x) {
      return x;
    }
    f() // undefined
    
    // 对象没有赋值的属性
    var  o = new Object();
    o.p // undefined
    
    // 函数没有返回值时,默认返回 undefined
    function f() {}
    f() // undefined
    

    三、布尔值

    布尔值为false的六种情况:undefined,null,false,0,NAN,""(空字符串),其它情况都是真
    

    四、数值

    JavaScript内部,所有数字都是以64位浮点数形式储存,整数也是一样

    1 === 1.0  //true
    

    由于浮点数不是精确的值,所以涉及小鼠的比较和运算要特别小心。

    0.1+0.2===0.3   //false
    0.3/0.1       // 2.99999999999
    (0.3-0.2) === (0.2-0.1)   // false
    
    • NAN:是JavaScript的特殊值,表示"非数字",主要出现在将字符串解析成数字出错的场合

      s-"x"   // NAN(Not A Number)
      0/0     //NAN
      
    • 注意NAN不是一种数据类型,是一个值,它的数据类型依然是Number

      typeof NAN  // 'number'
      
    • NAN不等于任何值,包括它本身

      NAN === NAN    // false
      
    • NAN与任何数(包括它自己)的运算,得到的结果都是NAN

      NAN+11  // NAN
      NAN+22  // NAN
      NAN+NAN // NAN
      

    Infinity 表示无穷,-infinity表示负无穷

    与数值相关的全局方法

    • parseint:将字符串转换为整数,如果头部有空格会自动帮忙去除

      parseint("   123")    // 123
      parseint(1.23)        // 1
      
      // 字符串转换为整数的时候,是一个一个字符一次转换,如果不能转换了,就返回之前转好的部分
      parseint("123adasd")  // 123
      parseint("asdasd")
      
      // 进制转换
      parseint("1000");
      parseint("1000",10)      // 两者都是1000
      
      parseint("1000",2)    //8
      parseint("1000",6)    // 216
      
    • parsefloat:将一个字符串转为浮点数

    • isNAN:用来判断一个值是否为NAN,返回值为布尔

      isNAN(123)     //false
      isNAN("zhuyu") //true
      
    • isFinite : 返回一个布尔值,表示某个值是否为正常的数值

    五、字符串

    • 定义

      var str = 'a
      b
      c';
      // 上面这样的表示方法,是会报错的,改为下面这种
      var str = 'a
      b
      c';
      // 使用 + 号进行字符串的拼接
      var name = "zhu" + "yu";
      
    • 字符串与数组

      var str = "zhuyu";
      str[0] // "z"
      str[1] // "h"
      // 可以通过索引(下标)取值
      
      str[10] //undefined,索引值超过了str字符串的最大索引值,返回undefined
      
      // 字符串不能和数组那样,对元素进行增删改
      
    • length属性:返回字符串的长度

      var name = "zhuyu";
      name.lenght // 5
      

    六、对象:对象(object)是JavaScript语言的核心概念,也是最重要的数据类型

    • 生成方法

      var obj = {
          foo : "hello",
          bar : "world"
      }
      
    • 键名:对象的所有键名都是字符串,所以加不加引号都可以

      var obj = {
          foo:"hello",
          bar:"world"
      }
      
      // 如果键名是数值,会自动转换为字符串
      var objj = {
          1:"a",
          2:"b"
      }
      
    • 对象的引用

      如果不同的变量名指向同一个对象,那么它们都是这个对象的引用,也就是说指向同一个内存地址,修改其中一个变量,会影响到其他所有变量。

      var o1 = {};
      var o2 = o1;
      
      o2.name = "zhuyu";
      console.log(o1.name);    // zhuyu
      
      o1.age = 22;
      console.log(o2.age);     // 22
      
    • 属性操作:

      1. 读取对象属性有两种方法,以是.运算符,一种是方括号运算符

        var obj = {
            name:"zhuyu"
        }
        obj.name;   // zhuyu
        objp[name]; // zhuyu
        
        // 注意:数值键名不能使用.运算符,只能使用方括号运算符
        var aa = {
            1:"one"
        }
        aa.1;  // 报错
        aa[1]; // one
        
      2. 属性赋值

        var obj = {
            name:"zhuyu"
        };
        obj.age = 22;
        obj["sex"] = "男";
        
      3. 属性的查看

        var obj = {
            name:"zhuyu",
            age:22
        }
        Object.keys(obj);  // ["name","age"]
        
      4. 属性的删除

        var obj = {
            name:"zhuyu"
        }
        delete obj.name;
        // 注意删除一个不存在的键值,是不会报错的,返回值为True
        
      5. 属性是否存在:in运算符

        var obj = {
            name :"zhuyu"
        }
        "name" in obj;  //true
        "toString" in obj;  //true  结果是true,说明该属性存在,应该默认继承类中有这个属性
        
        // hasOwnProperty对象方法可以判断自身是否有什么属性
        
      6. 属性的遍历:for...in循环

        var obj = {
            a:1,
            b:2,
            c:3
        }
        for (var i in obj) {
            // i 就是键名
            console.log("键名:",i);
            console.log("键值:",obj[i]);
        }
        

        for...in 循环有两个使用注意点:

        • 它是遍历对象所有可以遍历的属性,会跳过不可遍历的属性
        • 它不仅遍历对象自身的属性,还可以遍历继承的属性
        // 只想遍历对象本身的属性
        var person = {
            name:"朱春宇"
        }
        for (key in person) {
            if (person.hasOwnProperty(key)) {
                console.log(key);
            }
        }
        
    • with 语句 : 操作同一个对象的多个属性时,提供一些书写的方便

      with 语句的格式如下

      with (对象) {
          语句;
      }
      
      var aa = {
          a1:1,
          a2:2
      }
      with (aa) {
          a1 = 11;
          a2 = 22;
      }
      // 等同于
      aa.a1 = 11;
      aa.a2 = 22;
      

      注意:with区域内部赋值操作,必须时对象已有的属性,否则会在当前作用域创建一个全局变量

      var aa = {};  // 一个空对象
      with (aa) {
          name = "zhuyu";
          age = 22;
      }
      aa.name;	// 
      name;        // zhuyu
      

    七、函数:函数是一段可以反复调用的代码块。

    • JavaScript有三种声明函数的方法

      1. function命令

        function print(str) {
            console.log(str);
        }
        
      2. 函数的表示式

        var print = function(str) {
            console.log(str);    
        }
        // 上面这种声明方式,function后不能带有函数名,如果加上了,那么该函数名只有在函数体内部有效,在函数外部是无效的。
        
        var print = function f () {
            console.log(typeof f);
        }
        f;  // f is not undefined;
        print(); // function
        
      3. Function构造函数

        var print = new Function(
        	"x",
            "return x";
        )
        
    • 函数的重复声明:同一个函数被多次声明,后面的声明就会覆盖前面的声明

      function f () {
          console.log(1);
      };
      function f () {
          console.log(2);
      };
      
      f(); // 2
      
    • 圆括号运算符,return语句和递归

      1. ():调用函数,参数写在括号里
      2. return:函数的返回值,不会再执行该函数的其他代码
      3. 函数里还可以调用函数本身,但是必须要有一个结束的标志,不然会无限循环
    • 第一公民

      function add(x, y) {
        return x + y;
      }
      
      // 将函数赋值给一个变量
      var operator = add;
      
      // 将函数作为参数和返回值
      function a(op){
        return op;
      }
      a(add)(1, 1)
      // 2
      
    • 函数名的提升

      JavaScript引擎将函数名同视为变量名,也有函数名的提升

      f();
      function f () {
          console.log(1);
      }
      
      ------------------------------
      
      var f = function () {
        console.log('1');
      };
      
      function f() {
        console.log('2');
      };
      
      f(); // 1
      
    • 函数的属性属性和方法

      1. name属性:获取函数的名字

        function f () {};
        f.name;  // f1
        ----------------------------
        var f2 = function () {};
        f2.name; // f2
        ----------------------------
        var f3 = function func () {};
        f3.name; // func
        
      2. length属性:返回函数参数的个数

        function f (a,b) {};
        f.length;  // 2
        

        length属性提供了一种机制,判断定义时和调用时参数的差异,以便实现面向对象编程的方法"方法重载"(overload)。

      3. toString:返回字符串,内容时函数的源码

        function f () {
            console.log("1");
        }
        f.toString();
        /*
        function f () {
            console.log("1");
        }
        */
        
    • 函数作用域

      1. 作用域指的是变量存在的范围。ES5中,JavaScript只有两种作用域,全局作用域,局部作用域

        全局作用域:函数外部声明的全局变量
        局部作用域:函数内部定义变量的一块空间
        
      2. 函数内部的变量提升

        与全局作用域一样,函数作用域内部也会产生"变量提升"现象。var命令声明的变量。不管在什么位置,变量声明都会被提升到函数体的头部

        function foo(x) {
          if (x > 100) {
            var tmp = x - 100;
          }
        }
        
        // 等同于
        function foo(x) {
          var tmp;
          if (x > 100) {
            tmp = x - 100;
          };
        }
        
      3. 函数本身的作用域

        函数本身也是一个值,也有自己的作用域。它的作用域与变量一样,就是其声明时所在的作用域,与其运行时所在的作用域无关

        var a = 1;
        var x = function () {
          console.log(a);
        };
        function f() {
          var a = 2;
          x();
        }
        f(); // 1
        
        --------------------------
        var x = function () {
          console.log(a);
        };
        function y(f) {
          var a = 2;
          f();
        }
        y(x)
        // ReferenceError: a is not defined
        
        --------------------------
        function foo() {
          var x = 1;
          function bar() {
            console.log(x);
          }
          return bar;
        }
        var x = 2;
        var f = foo();
        f() // 1
        
    • 参数

      1. 概述:根据外部传递参数的不同,得到的返回值也不同

        function add (x,y) {
            return x+y;
        }
        add(1,2);          // 3
        add(11,22);		  // 33
        
      2. 参数的省略:JavaScript对函数的要求不高,你可以多传,也可以不传

        function print (a,b) {
            return a;
        };
        print(1,2,3);  // 1
        print(1);      // 1
        print();       // undefined
        
      3. 参数传递方式

        函数参数如果时原始类型的值(数值,字符串,布尔值),传递方式为值传递

        var name = "zhuyu";
        function setName (str) {
            str = "zhanghao";
        };
        setName(name);
        name;       // zhuyu
        

        函数参数是复合类型的值(数值,对象,其他函数),传递方式为址传递(也就是内存地址)

        var obj = {
            name:"zhuyu"
        }
        function setName (obj) {
            obj.name = "zhanghao";
        };
        setName(obj);
        obj.name;  // zhanghao
        
        ----------------------------
        
        var obj = [2,4,6]
        function setName (obj) {
            obj = [1,2,3]
        };
        setName(obj);
        obj;  // [2,4,6]
        /*
        解析上面这段代码,函数里的参数obj,在开始对应的是[2,4,6]对应的内存地址,再执行obj=[1,2,3],它是将[1,2,3]的内存地址赋值给它了,并没有改变[2,4,6]的值,所以函数执行完毕,obj这个变量对应的内存地址是没有改变的。
        */
        
      4. 同名参数

        function f (a,a) {
            console.log(a);
        }
        f(1,3);  // 3
        
      5. arguments对象

        由于JavaScript允许函数有不定数的参数,所以需要一种机制,可以在函数体内部地区所有参数。这就是argument对象的由来

        function f (args) {
            console.log(argument[0]);
            console.log(argument[1]);
        };
        f(1,2);   // 1,2
        

        正常模式下,是可以改变argument对象内部的值

        function add (a,b) {
            argument[0] = 5;
            argument[1] = 5;
            retuen a+b
        };
        add(1,1);   // 10
        

        严格模式下,修改argument对象内部值,是不会影响实际参数传递

        function add (a,b) {
            "use strict"; // 开启严格模式
            argument[0] = 5;
            argument[1] = 5;
            retuen a+b
        };
        add(1,1);   // 2
        

        通过对象argumentlength属性,可以判断函数调用时到底带了几个参数

        function f () {
            return argument.length;
        };
        f(1,2,3,4);  // 4
        f();         // 0
        
    • 函数的其他知识点

      1. 闭包:JavaScript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现

        理解闭包,首先必须要理解变量作用域,函数内部可以直接读取全局变量的

        var n = 123;
        function f () {
            console.log(n);
        }
        f();  // 123
        

        写一个实现闭包的例子

        function aa () {
            var name = "zhuyu";
            function bb () {
                console.log(name);
            }
            return bb;
        }
        var bb = aa();
        bb();  // zhuyu
        

        闭包的最大用处有两个,一个时可以读取内部的变量,另一个就是让这些变量始终保存在内存中,即闭包可以使得它诞生环境一直在。

        // 闭包使得内部变量记住上一次调用时的运算结果。
        function createIncrementor(start) {
          return function () {
            return start++;
          };
        }
        
        var inc = createIncrementor(5);
        
        inc() // 5
        inc() // 6
        inc() // 7
        
        // 闭包的另一个用处,是封装对象的私有属性和私有方法。
        function Person(name) {
          var _age;
          function setAge(n) {
            _age = n;
          }
          function getAge() {
            return _age;
          }
        
          return {
            name: name,
            getAge: getAge,
            setAge: setAge
          };
        }
        
        var p1 = Person('张三');
        p1.setAge(25);
        p1.getAge() // 25
        
      2. 立即调用的函数表达式

        (function () {}());
        
    • eval命令

      1. 基本用法:eval命令接受一个字符串作为参数,并将这个字符串党委语句执行

        eval("var a= 1;");
        a; // 1
        

        参数字符串无法当作语句运行,就会报错

        eval("3x");  // 语法错误
        

        eval没有自己的作用域,都在当前作用域执行,可能会更改当前作用域的变量

        var a = 1;
        eval("a = 2");
        a; // 2
        

        为了防止这种风险,JavaScript规定,如果使用严格模式,eval内部声明的变量,不会影响到外部的作用域

        (function f() {
            "use strict";
            eval("var foo = 123");
            console.log(foo);     // undefined;
        })
        

        不过在严格模式下,eval依然可以读写当前作用域的变量

        (function f() {
          'use strict';
          var foo = 1;
          eval('foo = 2');
          console.log(foo);  // 2
        })()
        

        总之,eval的本质是在当前作用域之中,注入代码,一般不推荐使用,最常见的地方是解析JSON数据的字符串,不过正确的做法还是JSON.parse方法。

    八、数组:是按次序排列的一组值,每个值的位置都是有编号(从0开始),用[]表示

    • 定义数组

      var arr = [1,2,3];
      var arr2 = [{"name":"zhuyu"},[1,2,3],function(){return true}]
      
    • 数组的本质:属于一种特殊的对象,typeof返回的类型是object

      typeof [1,2];    // object
      
      var arr = ["a","b","c"];
      object.keys(arr);     // ["0","1","2"]
      

      JavaScript规定对象的键名必须是字符串

      var arr = [1,2];
      arr[0];   // 1
      arr["0"]; // 1
      
      // 这是因为被自动转换成了字符串
      
    • length属性:返回数组的成员个数

      ["a","b","c"].length  // 3
      

      length属性是可写的,如果人为设置一个小于当前成员的个数,那么数组会自动减少到设置length的值

      var arr = ["a","b","c","d"];
      arr.length;  // 4
      
      arr.length = 2;
      arr;         // ["a","b"]
      
      arr.length = 100;
      arr[80];     // undefined
      

      清空数组的方法:arr.length=0;

      数组也是一种特殊的对象,可以为它添加属性,不会影响到length的长度

      var arr = [];
      arr["name"] = "zhuyu";
      arr.length;  // 0
      arr["age"] = 23;
      arr.length;  // 0
      
    • in运算符:检测某个键名是否存在,适用于对象,也适用于数组

    • for...in :遍历整个数组

      var arr = ["a","b","c"];
      arr["name"] = "zhuyu";
      for (var i in arr) {
          console.log(i);
      }
      // 输出效果为 0,1,2,name
      
    • 数组的空位:数组的某个元素是空元素,即两个逗号之间没有任何值

      var a = [1,,1];
      a.length; // 输出为3
      
      a[1];     // undefined
      

      使用delete命令删除一个数组成员,会形成空位,并且不会影响lenght属性

      var arr = [1,2,3];
      delete arr[0];
      arr.length;  // 3
      arr[0];      // undefined
      
    • 类似数组的对象

      如果一个对象的所有键名都是正整数或零,并且有length属性,那么这个对象就很像数组,称为"类数组对象"。

  • 相关阅读:
    算法提高 道路和航路
    奇偶剪枝
    二分求值
    并查集--路径压缩
    Oracle数据库导入导出DMP文件
    Spring IoC的实现与思考(一)
    sql基础拾遗
    jquery事件函数的使用之focus
    Java动态代理之cglib
    Java se之动态代理
  • 原文地址:https://www.cnblogs.com/zhuchunyu/p/10648643.html
Copyright © 2011-2022 走看看