【零基础JavaScript初阶】 数据类型

1.分类:

1.原始类型(6种

  • Undefined
  • Null
  • Boolean
  • Number
  • String
  • Symbol

2. 对象类型

  • Object: 任意对象
  • Funtion: 一种特别的对象(可以执行)
  • Array: 一种特别的对象(数值下标,内部数据是有序的)

2.判断

因为ECMAScript的类型系统是松散的,所以需要一种手段来确定任意变量的数据类型。typeof操作符就是为此而生的。对一个值使用typeof操作符会返回下列字符串之一:

  • "undefined"表示值未定义;
  • "boolean"表示值为布尔值;
  • "string"表示值为字符串;
  • "number"表示值为数值;
  • "object"表示值为对象(而不是函数)或null;
  • "function"表示值为函数;
  • "symbol"表示值为符号。

注意:严格来讲,函数在ECMAScript中被认为是对象,并不代表一种数据类型。可是,函数也有自己特殊的属性。为此,就有必要通过typeof操作符来区分函数和其他对象。

1.1 Undefined类型

Undefined类型只有一个值,就是特殊值undefined。当使用var或let声明了变量但没有初始化时,就相当于给变量赋予了undefined值:

    let message;
    console.log(message == undefined); // true

注意 :即使未初始化的变量会被自动赋予undefined值,但我们仍然建议在声明变量的同时进行初始化。这样,当typeof返回"undefined"时,你就会知道那是因为给定的变量尚未声明,而不是声明了但未初始化。

1.2 Null类型

Null类型同样只有一个值,即特殊值null。逻辑上讲,null值表示一个空对象指针,这也是给typeof传一个null会返回"object"的原因:

    let car = null;
    console.log(typeof car);   // "object"

在定义将来要保存对象值的变量时,建议使用null来初始化,不要使用其他值。这样,只要检查这个变量的值是不是null就可以知道这个变量是否在后来被重新赋予了一个对象的引用。

1.3 Boolean类型

Boolean(布尔值)类型是ECMAScript中使用最频繁的类型之一,有两个字面值:truefalse。这两个布尔值不同于数值,因此true不等于1,false不等于0。下面是给变量赋布尔值的例子:

    let found = true;
    let lost = false;

注意: 布尔值字面量 true 和 false 是区分大小写的。

Boolean()转型函数可以在任意类型的数据上调用,而且始终返回一个布尔值。什么值能转换为true或false的规则取决于数据类型和实际的值。下表总结了不同类型与布尔值之间的转换规则。

数据类型

转换为true的值

转换为false的值

Boolean

true

false

String

非空字符创

" "(空字符创)

Number

非零数值(包括无穷值)

0,NaN

Object

任意对象

null

Undefined

N/A(不存在)

undefined

理解以上转换非常重要,因为像if等流控制语句会自动执行其他类型值到布尔值的转换,例如:

    let message = "Hello world! ";
    if (message) {
      console.log("Value is true");
    }

在这个例子中,console.log会输出字符串"Value is true",因为字符串message会被自动转换为等价的布尔值true。由于存在这种自动转换,理解流控制语句中使用的是什么变量就非常重要。错误地使用对象而不是布尔值会明显改变应用程序的执行流。

1.4 Number类型

ECMAScript中最有意思的数据类型或许就是Number了。Number类型表示整数和浮点值(在某些语言中也叫双精度值)。不同的数值类型相应地也有不同的数值字面量格式。

最基本的数值字面量格式是十进制整数,直接写出来即可:

   let intNum = 55;   // 整数

要定义浮点值,数值中必须包含小数点,而且小数点后面必须至少有一个数字。虽然小数点前面不是必须有整数,但推荐加上。下面是几个例子:

    let floatNum1 = 1.1;
    let floatNum2 = 0.1;
    let floatNum3 = .1;    // 有效,但不推荐

有一个特殊的数值叫NaN,意思是“不是数值”(Not a Number),用于表示本来要返回数值的操作失败了(而不是抛出错误)。

数值转换:

有3个函数可以将非数值转换为数值

  • Number() -> 可用于任何数据类型
  • parseInt() -> 主要用于将字符串转换为数值
  • parseFloat() -> 主要用于将字符串转换为数值

对于同样的参数,这3个函数执行的操作也不同。

Number()函数基于如下规则执行转换。

  • 布尔值,true转换为1,false转换为0。
  • 数值,直接返回。
  • null,返回0。
  • undefined,返回NaN。
  • 字符串,应用以下规则。
    • 如果字符串包含数值字符,包括数值字符前面带加、减号的情况,则转换为一个十进制数值。因此,Number("1")返回1, Number("123")返回123, Number("011")返回11(忽略前面的零)。
    • 如果字符串包含有效的浮点值格式如"1.1",则会转换为相应的浮点值(同样,忽略前面的零)。
    • 如果字符串包含有效的十六进制格式如"0xf",则会转换为与该十六进制值对应的十进制整数值。
    • 如果是空字符串(不包含字符),则返回0。
    • 如果字符串包含除上述情况之外的其他字符,则返回NaN。
  • 对象,调用valueOf()方法,并按照上述规则转换返回的值。如果转换结果是NaN,则调用toString()方法,再按照转换字符串的规则转换。

考虑到用Number()函数转换字符串时相对复杂且有点反常规,通常在需要得到整数时可以优先使用parseInt()函数。parseInt()函数更专注于字符串是否包含数值模式。

下面几个转换示例有助于理解parseInt():

    let num1 = parseInt("1234blue");   // 1234
    let num2 = parseInt("");             // NaN
    let num3 = parseInt("0xA");         // 10,解释为十六进制整数
    let num4 = parseInt(22.5);          // 22
    let num5 = parseInt("70");          // 70,解释为十进制值
    let num6 = parseInt("0xf");         // 15,解释为十六进制整数

不同的数值格式很容易混淆,因此parseInt()也接收第二个参数,用于指定底数(进制数)。如果知道要解析的值是十六进制,那么可以传入16作为第二个参数,以便正确解析:

    let num = parseInt("0xAF", 16); // 175

通过第二个参数,可以极大扩展转换后获得的结果类型。比如:

    let num1 = parseInt("10", 2);    // 2,按二进制解析
    let num2 = parseInt("10", 8);    // 8,按八进制解析
    let num3 = parseInt("10", 10);   // 10,按十进制解析
    let num4 = parseInt("10", 16);   // 16,按十六进制解析

parseFloat()函数与parseInt()函数的不同点:

  • 可以解析浮点数值字符
  • 忽略字符串开头的零。比如十六进制数值始终会返回0。
  • 只能解析十进制值,不能指定底数。
    let num1 = parseFloat("1234blue");   // 1234,按整数解析
    let num2 = parseFloat("0xA");         // 0
    let num3 = parseFloat("22.5");        // 22.5
    let num4 = parseFloat("22.34.5");    // 22.34
    let num5 = parseFloat("0908.5");     // 908.5
    let num6 = parseFloat("3.125e7");    // 31250000

1.5 String类型

字符串可以使用双引号(")、单引号(')或反引号(`)标示,因此下面的代码都是合法的:

    let firstName = "John";
    let lastName = 'Jacob';
    let lastName = `Jingleheimerschmidt`

跟某些语言中使用不同的引号会改变对字符串的解释方式不同,ECMAScript语法中表示字符串的引号没有区别。不过要注意的是,以某种引号作为字符串开头,必须仍然以该种引号作为字符串结尾。比如,下面的写法会导致语法错误:

    let firstName = 'Nicholas"; //语法错误:开头和结尾的引号必须是同一种

1. 字符字面量

字符串数据类型包含一些字符字面量,用于表示非打印字符或有其他用途的字符,如下表所示:

2. 字符串的特点

ECMAScript中的字符串是不可变的(immutable),意思是一旦创建,它们的值就不能变了。要修改某个变量中的字符串值,必须先销毁原始的字符串,然后将包含新值的另一个字符串保存到该变量,如下所示:

    let lang = "Java";
    lang = lang + "Script";

这里,变量lang一开始包含字符串"Java"。紧接着,lang被重新定义为包含"Java"和"Script"的组合,也就是"JavaScript"。整个过程首先会分配一个足够容纳10个字符的空间,然后填充上"Java"和“Script”。最后销毁原始的字符串"Java"和字符串"Script",因为这两个字符串都没有用了。

3. 转换为字符串

有两种方式把一个值转换为字符串:toString() String()

toString()函数:

toString()方法可见于数值、布尔值、对象和字符串值。null和undefined值没有toString()方法。这个方法唯一用途就是返回当前的字符串等价物。比如:

    let age = 11;
    let ageAsString = age.toString();        // 字符串"11"
    let found = true;
    let foundAsString = found.toString();    //字符串"true"

String()函数:

如果你不确定一个值是不是null或undefined,可以使用String()转型函数,它始终会返回表示相应类型值的字符串。String()函数遵循如下规则。

  • 如果值有toString()方法,则调用该方法并返回结果。
  • 如果值是null,返回"null"。
  • 如果值是undefined,返回''undefined''。
    let value1 = 10;
    let value2 = true;
    let value3 = null;
    let value4;
    console.log(String(value1)); // "10"
    console.log(String(value2));   // "true"
    console.log(String(value3));   // "null"
    console.log(String(value4));   // "undefined"

注意:用加号操作符给值加上一个空字符串""也可以将其转换为字符串。

4. 模板字面量

ECMAScript 6新增了使用模板字面量定义字符串的能力。与使用单引号或双引号不同,模板字面量保留换行字符,可以跨行定义字符串:

    let myMultiLineString = 'first line\nsecond line';
    let myMultiLineTemplateLiteral = `first line
    second line`;
    console.log(myMultiLineString);
    // "first line
    // second line"
    console.log(myMultiLineTemplateLiteral);
    // "first line
    // second line"
   console.log(myMultiLineString === myMultiLineTemplateLiteral); //true

顾名思义,模板字面量在定义模板时特别有用,比如下面这个HTML模板:

    let pageHTML = `
    <div>
      <a href="#">
        <span>Jake</span>
      </a>
    </div>`;

5. 字符串插值

模板字面量最常用的一个特性是支持字符串插值,也就是可以在一个连续定义中插入一个或多个值。技术上讲,模板字面量不是字符串,而是一种特殊的JavaScript句法表达式,只不过求值后得到的是字符串。模板字面量在定义时立即求值并转换为字符串实例,任何插入的变量也会从它们最接近的作用域中取值。

let value = 5;
let exponent = 'second';
// 以前,字符串插值是这样实现的:
let interpolatedString =
    value + ' to the ' + exponent + ' power is ' + (value * value);
// 现在,可以用模板字面量这样实现:
let interpolatedTemplateLiteral =
    `${ value } to the ${ exponent } power is ${ value * value }`;
console.log(interpolatedString);           // 5 to the second power is 25
console.log(interpolatedTemplateLiteral); // 5 to the second power is 25

所有插入的值都会使用toString()强制转型为字符串,而且任何JavaScript表达式都可以用于插值。

1.6 Object类型

ECMAScript中的对象其实就是一组数据和功能的集合。对象通过new操作符后跟对象类型的名称来创建。开发者可以通过创建Object类型的实例来创建自己的对象,然后再给对象添加属性和方法:

    let o = new Object();

每个Object实例都有如下属性和方法。

  • constructor:用于创建当前对象的函数。在前面的例子中,这个属性的值就是Object()函数。
  • hasOwnProperty(propertyName):用于判断当前对象实例(不是原型)上是否存在给定的属性。要检查的属性名必须是字符串(如o.hasOwnProperty("name"))或符号。
  • isPrototypeOf(object):用于判断当前对象是否为另一个对象的原型。
  • propertyIsEnumerable(propertyName):用于判断给定的属性是否可以使用for-in语句枚举。与hasOwnProperty()一样,属性名必须是字符串。、
  • toLocaleString():返回对象的字符串表示,该字符串反映对象所在的本地化执行环境。
  • toString():返回对象的字符串表示。
  • valueOf():返回对象对应的字符串、数值或布尔值表示。通常与toString()的返回值相同。

因为在ECMAScript中Object是所有对象的基类,所以任何对象都有这些属性和方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值