美文网首页
javascript数据类型

javascript数据类型

作者: 崔磊8080 | 来源:发表于2018-07-24 22:41 被阅读26次

    JavaScript 语言的每一个值,都属于某一种数据类型。JavaScript 的数据类型,共有六种。(ES6 又新增了第七种 Symbol 类型的值。)

    • 数值(number):整数和小数(比如13.14
    • 字符串(string):文本(比如Hello World)。
    • 布尔值(boolean):表示真伪的两个特殊值,即true(真)和false(假)
    • undefined:表示“未定义”或不存在,即由于目前没有定义,所以此处暂时没有任何值
    • null:表示空值,即此处的值为空。
    • 对象(object):各种值组成的集合。
    • symbol一种数据类型,它的实例是唯一且不可改变的。

    数值、字符串、布尔值这三种类型,合称为原始类型(primitive type)的值,即它们是最基本的数据类型,不能再细分了。

    至于undefinednull,一般将它们看成两个特殊值。

    对象则称为合成类型(complex type)的值,因为一个对象往往是多个原始类型的值的合成,可以看作是一个存放各种值的容器。

    对象是最复杂的数据类型,又可以分成三个子类型。

    • 狭义的对象(object)
    • 数组(array)
    • 函数(function)

    函数其实是处理数据的方法,JavaScript 把它当成一种数据类型,可以赋值给变量,这为编程带来了很大的灵活性,也为 JavaScript 的“函数式编程”奠定了基础。

    如何确定类型

    JavaScript 有三种方法,可以确定一个值到底是什么类型。

    • typeof运算符
    • instanceof运算符
    • Object.prototype.toString方法

    null, undefined

    nullundefined都可以表示“没有”,含义非常相似。将一个变量赋值为undefinednull,老实说,语法效果几乎没区别。

    既然含义与用法都差不多,为什么要同时设置两个这样的值,这不是无端增加复杂度,令初学者困扰吗?这与历史原因有关。

    1995年 JavaScript 诞生时,最初像 Java 一样,只设置了null表示"无"。根据 C 语言的传统,null可以自动转为0null转为数字时,自动变成0。

    但是,JavaScript 的设计者 Brendan Eich,觉得这样做还不够。首先,第一版的 JavaScript 里面,null就像在 Java 里一样,被当成一个对象,Brendan Eich 觉得表示“无”的值最好不是对象。其次,那时的 JavaScript 不包括错误处理机制,Brendan Eich 觉得,如果null自动转为0,很不容易发现错误。

    因此,他又设计了一个undefined

    区别是这样的:null是一个表示“空”的对象,转为数值的时候为0undefined是一个表示"此处无定义"的原始值,转为数值时为NaN

    null表示空值,即该处的值现在为空。调用函数时,某个参数未设置任何值,这时就可以传入null,表示该参数为空。比如,某个函数接受引擎抛出的错误作为参数,如果运行过程中未出错,那么这个参数就会传入null,表示未发生错误。

    undefined表示“未定义”,下面是返回undefined的典型场景。

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

    布尔值

    布尔值代表“真”和“假”两个状态。“真”用关键字true表示,“假”用关键字false表示。布尔值只有这两个值。

    下列运算符会返回布尔值:

    • 两元逻辑运算符: && (And),|| (Or)
    • 前置逻辑运算符: ! (Not)
    • 相等运算符:===!====!=
    • 比较运算符:>>=<<=

    如果 JavaScript 预期某个位置应该是布尔值,会将该位置上现有的值自动转为布尔值。转换规则是除了下面六个值被转为false,其他值都视为true

    • undefined
    • null
    • false
    • 0
    • NaN
    • ""''(空字符串)

    注意,空数组([])和空对象({})对应的布尔值,都是true

    true == 1
    true
    
    false == 0
    true
    
    typeof(NaN)
    "number"
    
    typeof(null)
    "object"
    
    typeof(undefined)
    "undefined"
    
    null == undefined
    true
    

    数值

    JavaScript 内部,所有数字都是以64位浮点数形式储存,即使整数也是如此。所以,11.0是相同的,是同一个数。

    1 === 1.0 // true
    

    这就是说,JavaScript 语言的底层根本没有整数,所有数字都是小数(64位浮点数)。容易造成混淆的是,某些运算只有整数才能完成,此时 JavaScript 会自动把64位浮点数,转成32位整数,然后再进行运算,参见《运算符》一章的”位运算“部分。

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

    0.1 + 0.2 === 0.3
    // false
    
    0.3 / 0.1
    // 2.9999999999999996
    
    (0.3 - 0.2) === (0.2 - 0.1)
    // false
    

    数值精度

    根据国际标准 IEEE 754,JavaScript 浮点数的64个二进制位,从最左边开始,是这样组成的。

    • 第1位:符号位,0表示正数,1表示负数
    • 第2位到第12位(共11位):指数部分
    • 第13位到第64位(共52位):小数部分(即有效数字)

    符号位决定了一个数的正负,指数部分决定了数值的大小,小数部分决定了数值的精度。

    指数部分一共有11个二进制位,因此大小范围就是0到2047。IEEE 754 规定,如果指数部分的值在0到2047之间(不含两个端点),那么有效数字的第一位默认总是1,不保存在64位浮点数之中。也就是说,有效数字这时总是1.xx...xx的形式,其中xx..xx的部分保存在64位浮点数之中,最长可能为52位。因此,JavaScript 提供的有效数字最长为53个二进制位。

    (-1)^符号位 * 1.xx...xx * 2^指数部分
    

    上面公式是正常情况下(指数部分在0到2047之间),一个数在 JavaScript 内部实际的表示形式。

    精度最多只能到53个二进制位,这意味着,绝对值小于等于2的53次方的整数,即-253到253,都可以精确表示。

    (0.1).toString(2)
    "0.0001100110011001100110011001100110011001100110011001101"
    
    //十进制转其他  
    var x=110;  
    alert(x);  
    alert(x.toString(8));  
    alert(x.toString(32));  
    alert(x.toString(16));  
    //其他转十进制  
    var x='110';  
    alert(parseInt(x,2));  
    alert(parseInt(x,8));  
    alert(parseInt(x,16));  
    //其他转其他  
    //先用parseInt转成十进制再用toString转到目标进制  
    alert(String.fromCharCode(parseInt(141,8)))  
    alert(parseInt('ff',16).toString(2));   
    
    相关
    toPrecision(17) 
    Math.pow
    

    字符串

    如果要在单引号字符串的内部,使用单引号,就必须在内部的单引号前面加上反斜杠,用来转义。双引号字符串内部使用双引号,也是如此。

    'Did she say \'Hello\'?'
    // "Did she say 'Hello'?"
    
    "Did she say \"Hello\"?"
    // "Did she say "Hello"?"
    

    字符串默认只能写在一行内,分成多行将会报错。

    'a
    b
    c'
    // SyntaxError: Unexpected token ILLEGAL
    

    转义

    反斜杠(\)在字符串内有特殊含义,用来表示一些特殊字符,所以又称为转义符。

    需要用反斜杠转义的特殊字符,主要有下面这些。

    • \0 :null(\u0000
    • \b :后退键(\u0008
    • \f :换页符(\u000C
    • \n :换行符(\u000A
    • \r :回车键(\u000D
    • \t :制表符(\u0009
    • \v :垂直制表符(\u000B
    • \' :单引号(\u0027
    • \" :双引号(\u0022
    • \\ :反斜杠(\u005C

    (1)\HHH

    反斜杠后面紧跟三个八进制数(000377),代表一个字符。HHH对应该字符的 Unicode 码点,比如\251表示版权符号。显然,这种方法只能输出256种字符。

    (2)\xHH

    \x后面紧跟两个十六进制数(00FF),代表一个字符。HH对应该字符的 Unicode 码点,比如\xA9表示版权符号。这种方法也只能输出256种字符。

    (3)\uXXXX

    \u后面紧跟四个十六进制数(0000FFFF),代表一个字符。XXXX对应该字符的 Unicode 码点,比如\u00A9表示版权符号。

    下面是这三种字符特殊写法的例子。

    '\251' // "©"
    '\xA9' // "©"
    '\u00A9' // "©"
    
    '\172' === 'z' // true
    '\x7A' === 'z' // true
    '\u007A' === 'z' // true
    

    字符串与数组

    字符串可以被视为字符数组,因此可以使用数组的方括号运算符,用来返回某个位置的字符(位置编号从0开始)。

    var s = 'hello';
    s[0] // "h"
    s[1] // "e"
    s[4] // "o"
    
    // 直接对字符串使用方括号运算符
    'hello'[1] // "e"
    

    如果方括号中的数字超过字符串的长度,或者方括号中根本不是数字,则返回undefined

    'abc'[3] // undefined
    'abc'[-1] // undefined
    'abc'['x'] // undefined
    

    但是,字符串与数组的相似性仅此而已。实际上,无法改变字符串之中的单个字符。

    var s = 'hello';
    
    delete s[0];
    s // "hello"
    
    s[1] = 'a';
    s // "hello"
    
    s[5] = '!';
    s // "hello"
    

    上面代码表示,字符串内部的单个字符无法改变和增删,这些操作会默默地失败。

    字符集

    JavaScript 使用 Unicode 字符集。JavaScript 引擎内部,所有字符都用 Unicode 表示。

    JavaScript 不仅以 Unicode 储存字符,还允许直接在程序中使用 Unicode 码点表示字符,即将字符写成\uxxxx的形式,其中xxxx代表该字符的 Unicode 码点。比如,\u00A9代表版权符号。

    var s = '\u00A9';
    s // "©"
    

    解析代码的时候,JavaScript 会自动识别一个字符是字面形式表示,还是 Unicode 形式表示。输出给用户的时候,所有字符都会转成字面形式。

    var f\u006F\u006F = 'abc';
    foo // "abc"
    

    上面代码中,第一行的变量名foo是 Unicode 形式表示,第二行是字面形式表示。JavaScript 会自动识别。

    我们还需要知道,每个字符在 JavaScript 内部都是以16位(即2个字节)的 UTF-16 格式储存。也就是说,JavaScript 的单位字符长度固定为16位长度,即2个字节。

    但是,UTF-16 有两种长度:对于码点在U+0000U+FFFF之间的字符,长度为16位(即2个字节);对于码点在U+10000U+10FFFF之间的字符,长度为32位(即4个字节),而且前两个字节在0xD8000xDBFF之间,后两个字节在0xDC000xDFFF之间。举例来说,码点U+1D306对应的字符为𝌆,它写成 UTF-16 就是0xD834 0xDF06

    JavaScript 对 UTF-16 的支持是不完整的,由于历史原因,只支持两字节的字符,不支持四字节的字符。这是因为 JavaScript 第一版发布的时候,Unicode 的码点只编到U+FFFF,因此两字节足够表示了。后来,Unicode 纳入的字符越来越多,出现了四字节的编码。但是,JavaScript 的标准此时已经定型了,统一将字符长度限制在两字节,导致无法识别四字节的字符。上一节的那个四字节字符𝌆,浏览器会正确识别这是一个字符,但是 JavaScript 无法识别,会认为这是两个字符。

    '𝌆'.length // 2
    

    上面代码中,JavaScript 认为𝌆的长度为2,而不是1。

    总结一下,对于码点在U+10000U+10FFFF之间的字符,JavaScript 总是认为它们是两个字符(length属性为2)。所以处理的时候,必须把这一点考虑在内,也就是说,JavaScript 返回的字符串长度可能是不正确的。

    Base64 转码

    文本里面包含一些不可打印的符号,比如 ASCII 码0到31的符号都无法打印出来,这时可以使用 Base64 编码,将它们转成可以打印的字符。另一个场景是,有时需要以文本格式传递二进制数据,那么也可以使用 Base64 编码。

    所谓 Base64 就是一种编码方法,可以将任意值转成 0~9、A~Z、a-z、+/这64个字符组成的可打印字符。使用它的主要目的,不是为了加密,而是为了不出现特殊字符,简化程序的处理。

    JavaScript 原生提供两个 Base64 相关的方法。

    • btoa():任意值转为 Base64 编码
    • atob():Base64 编码转为原来的值
    var string = 'Hello World!';
    btoa(string) // "SGVsbG8gV29ybGQh"
    atob('SGVsbG8gV29ybGQh') // "Hello World!"
    

    注意,这两个方法不适合非 ASCII 码的字符,会报错。

    btoa('你好') // 报错
    

    要将非 ASCII 码字符转为 Base64 编码,必须中间插入一个转码环节,再使用这两个方法。

    function b64Encode(str) {
      return btoa(encodeURIComponent(str));
    }
    
    function b64Decode(str) {
      return decodeURIComponent(atob(str));
    }
    
    b64Encode('你好') // "JUU0JUJEJUEwJUU1JUE1JUJE"
    b64Decode('JUU0JUJEJUEwJUU1JUE1JUJE') // "你好"
    

    对象

    JavaScript中的所有事物都被当作对象,JavaScript 提供多个内建对象,比如 String、Date、Array 等等。
    对象只是带有属性和方法的特殊数据类型。

    对象(object)是 JavaScript 语言的核心概念,也是最重要的数据类型。其基本数据结构是hash table。在python中为dictionaries,在ruby中为hashes。

    什么是对象?简单说,对象就是一组“键值对”(key-value)的集合,是一种无序的复合数据集合。

    对象的所有键名都是字符串(ES6 又引入了 Symbol 值也可以作为键名),所以加不加引号都可以。上面的代码也可以写成下面这样。

    如果键名是数值,会被自动转为字符串。

    如果键名不符合标识名的条件(比如第一个字符为数字,或者含有空格或运算符),且也不是数字,则必须加上引号,否则会报错。

    Property accessors

    括号记法始终可行。点记法要求属性名称以字母开头,不包含特殊字符。

    • true

      • "property1"
      • "property$"
    • false

      • "property-2"
      • "property 3"
      • " property"
      • "property "
      • "property[]"
      • "8property"
    var a = {c:'hi'}
    undefined
    
    var c = 'hello world'
    undefined
    
    a.c
    "hi"
    
    a[c]
    undefined
    
    a['c']
    "hi"
    
    c
    "hello world"
    //总结
    object.property//property为字符串在object中
    object[property]//property可以是变量名或字符串。
    
    • 查看属性,可以使用Object.keys方法。

    • 删除属性delete obj.p // true

    • 属性是否存在:in 运算符

    • 属性的遍历:for...in 循环

    • with 语句

    相关文章

      网友评论

          本文标题:javascript数据类型

          本文链接:https://www.haomeiwen.com/subject/oucumftx.html