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属性,那么这个对象就很像数组,称为"类数组对象"。

  • 相关阅读:
    一个简单的knockout.js 和easyui的绑定
    knockoutjs + easyui.treegrid 可编辑的自定义绑定插件
    Knockout自定义绑定my97datepicker
    去除小数后多余的0
    Windows Azure Web Site (15) 取消Azure Web Site默认的IIS ARR
    Azure ARM (1) UI初探
    Azure Redis Cache (3) 创建和使用P级别的Redis Cache
    Windows Azure HandBook (7) 基于Azure Web App的企业官网改造
    Windows Azure Storage (23) 计算Azure VHD实际使用容量
    Windows Azure Virtual Network (11) 创建VNet-to-VNet的连接
  • 原文地址:https://www.cnblogs.com/zhuchunyu/p/10648643.html
Copyright © 2011-2022 走看看