JS 语言基础笔记——第二篇(typeof操作符、简单数据类型(不包括Symbol))

前言

本篇笔记 JS 语言基础 第二篇。
主要包含内容为:

  • typeof 操作符和 ES5 中的简单数据类型

复杂数据类型 Object 和 ES6 新增的 Symbol 类型在下一篇。

数据类型

六种简单数据类型(原始类型):

UndefinedNullBooleanNumberStringSymbol(ES6新增)
未定义布尔数值字符串符号

复杂数据类型:
Object(对象),是一种无序名值对的集合(感觉可以理解为 python 的字典类型)。

1、typeof操作符

typeof会返回的值:

undefinedbooleannumberstringsymbolobjectfunction
值未定义值为布尔值为数值值为字符串值为符号值为对象或null值为函数
console.log(typeof message);  // undefined
console.log(typeof true);  // boolean
console.log(typeof 1);  // number
console.log(typeof 'hello');  // string
console.log(typeof {a: 'a'});  // object
console.log(typeof {});  // object
console.log(typeof null);  // object
function test(){}
console.log(typeof test); // function
let sym = Symbol();
console.log(typeof sym); // symbol

调用 “typeof null” 返回的 “object” ,这是因为 null 被认为是一个对空对象的引用。
严格来说,函数在 ECMAScript 中被认为是对象,并不代表一种数据类型。可是,函数也有自己的特殊属性。为此就有必要通过 typeof 来区分函数和其他对象。

2、Undefined类型

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

var message;
let msg;
console.log(message, msg);  // undefined undefined

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

// let msg2;
console.log(typeof msg2);
// undefined, msg2未声明,但返回值也是 undefined

增加 undefined 的目的就是为了正式明确空对象指针( null )和未初始化变量的区别。

当声明了变量值为 undefined 时,使用 if 语句, 如下:

var message;
if (message) {
    console.log(message);  // 无输出
}
if (!message) {
    console.log(message);  // undefined
}

3、Null类型

Null 类型同样只有一个值,null。调用 “typeof null” 返回的 “object” ,这是因为 null 被认为是一个对空对象的引用。

console.log(typeof null);  // object
  1. 在定义将来要保存对象值的变量时,建议使用 null 来初始化。这样,只要检查这个变量的值是不是 null 就可以知道这个变量是否在后来被重新赋予了一个对象的引用。
    如:
let message = null;
if (!message) {
    console.log('message is null');  // message is null
}
  1. undefined 值是由 null 值派生来的,因此 ECMA-262 将他们定义为表面上相等,如:
console.log(undefined == null); // true

3、Boolean类型

Boolean 类型有两个值,true 和 false。
不同类型值转换为布尔值的转换规则:

数据类型转换为 true转换为 false
Booleantruefalse
String非空字符串空字符串( “” )
Number非零数值(包括无穷值)0、NaN
Object任意对象null
UndefinedN/A(不存在)undefined

4、Number类型

Number 类型使用 IEEE 754 格式表示整数和浮点数。

(1)整数

  1. 十进制整数
let num_10 = 55;
  1. 八进制整数
let num_8 = 067;  // 八进制
console.log(num_8);  // 55  十进制
  1. 十六进制整数
let num_16 = 0x37;  // 十六进制
console.log(num_16);  // 55  十进制

(2)浮点数

定义浮点数必须包含小数点,且小数点后必须有数字。小数点前可以没有数字。
对于非常大或者非常小的数值,浮点值可以用科学计数法表示。格式为:一个 Number 类型(整数或浮点数)后跟一个 e 或 E,再加上要乘的10的多少次幂。如:

let floatNum = 1.25e4;
console.log(floatNum); // 12500

浮点数的精度最高可到 17 位小数,但在计算中不完全精准,例如:0.1 + 0.2 = 0.30000000000000004,而非0.3。由于这种微小的差异,导致很难测试特定的浮点值。

if (0.1 + 0.2 == 0.3) {
    console.log(true);
} else {
    console.log(false);
}  // false

这种差异是因为使用了 IEEE 754 数值,而非 ECMAScript 自身的问题。因此建议永远不要测试某个特定的浮点值。

(3)值的范围

console.log(Number.MAX_VALUE);
// 1.7976931348623157e+308  可表示的最大值
console.log(Number.MIN_VALUE);
// 5e-324  可表示的最小值

如果某个值超过了 js 可以表示的范围,那么这个数值会被自动转换为一个特殊的 Infinity 值(无穷)。任何无法表示的负值以 -Infinity(无穷小)表示,正值则用 Infinity(无穷大)表示。

Q:怎么判断一个值是不是无穷?
A:可以使用 isFinite() 函数测试一个值是不是无穷。如:

console.log(isFinite(Number.MAX_VALUE))  // true

(4)NaN(Not a Number)

特殊值 NaN 用来表示本来要返回数值的操作失败了(而不是抛出错误)。如下:

console.log(0 / 0);  // NaN
console.log(1 / 0);  // Infinity
console.log(-0 / +0);  // NaN
console.log(+0 / -0);  // NaN
console.log(1 / +0);  // Infinity
console.log(1 / -0);  // -Infinity

由上可知,当分子分母同为 0 时,返回值为 NaN;当分子不为0,分母为0时,返回值为 Infinity 或 -Infinity。不会有人会问还有一种情况吧?0 / 1 = 0 不知道啊?👀👀👀

NaN 的几个独特属性:

  1. 任何涉及NaN 的操作始终返回 NaN。如:
console.log(1 + NaN);  // NaN
console.log(1 - NaN);  // NaN
console.log(1 * NaN);  // NaN
console.log(1 / NaN);  // NaN
console.log(NaN / 1);  // NaN
  1. NaN 不等于包括 NaN 在内的所有值。如:
console.log(NaN  == NaN);  // false
console.log(NaN  === NaN);  // false

Q:怎么判断一个值是不是 NaN 呢?
A:使用 isNaN() 函数,参数可以是任意数据类型。如:

console.log(isNaN(NaN));  // true 
console.log(isNaN(1));  // false  数值 1 
console.log(isNaN('1'));  // false  可以转换成数值 1
console.log(isNaN('aaa'));  // true  不可以转换成数值 
console.log(isNaN({a: '1'}));  // true  不可以转换为数值
console.log(isNaN(true));  // flase  可以转换成数值 1
console.log(isNaN(null));  // false  可以转换成数值 0

(5)数值转换

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

  1. Number()

执行规则:

数据类型转换方式
Booleantrue 为 1,false 为 0
Number直接返回
Null返回 0
Undefined返回 NaN
String①如果是纯数值型(包括正负、浮点数、八进制、十六进制)的字符串,转换为十进制数值;
②如果是空字符串,转换为 0;
③如果非以上两种类型,返回 NaN。
Object先调用 valueof() 方法,按上述规则转换返回的值。如果转换结果为 NaN ,则调用 toString() 方法,再按照转换字符串的规则转换。

如下:

console.log(Number(1));  // 1
console.log(Number('1'));  // 1
console.log(Number('hello'));  // NaN
console.log(Number(''));  // 0
console.log(Number(true));  // 1
console.log(Number(false));  // 0
console.log(Number(undefined));  // NaN
  1. parseInt()

此函数更专注于将字符串是否包含数值模式,在需要得到整数时建议优先使用

转换时从第一个非空格字符开始转换,①若第一个非空格字符不是数值或正负号,则立即返回 NaN。与 Number() 不同的是,空字符串在此处也会返回 NaN,而不是 0。②若第一个字符是数值或正负号,则依次向下检测,直到碰到非数值字符或字符串末尾结束。如下:

console.log(parseInt('    123'));  // 123
console.log(parseInt(''));  // NaN
console.log(parseInt('-123abc'));  // -123
console.log(parseInt('abc123'));  // NaN
console.log(parseInt('1.1'));  // 1

同样的,此函数也能理解不同进制的参数,并返回相应的十进制整数。

上述为接收一个参数的形式,此函数还可以接收第二个参数:

console.log(parseInt('0x56', 16));  // 86  以十六进制输入第一个参数,返回该十六进制数的十进制数
console.log(parseInt('56', 16));  // 86  省略标识 0x 也行,但是得有第二个参数 16
console.log(parseInt('056', 8));  // 46  以八进制输入第一个参数,返回该八进制数的十进制数
console.log(parseInt('56', 8));  // 46  省略标识 0 也行,但是得有第二个参数 8
  1. parseFloat()

与 parseInt() 函数类似,但是它只解析十进制数,十六进制统统转化为 0 ,八进制转换为 0 后面跟的数值,如:0506 → 506。没有小数点或小数点后为 0,则转换为整数。

5、String类型

字符串可以用双引号,单添加链接描述引号或反引号标识。如:

let str1 = "aaaa";
let str2 = 'aaaa';
let str3 = `aaaa`;

(1)字符字面量

用 \ 定义,例如:\n,\t 等。具体可转至:
string字符串,模板字面量

(2)转换为字符串

  1. 首选:toString() 方法
    例如:
let num = 111,
    bool = true;
console.log(num.toString(), bool.toString());  // 111 true

一般来说,此方法没有接收参数,但是它也可以接受一个参数,表示用几进制来展示该值。如:

let num = 10;
console.log(num.toString());  // 10
console.log(num.toString(2));  // 1010
console.log(num.toString(8));  // 12
console.log(num.toString(10));  // 10
console.log(num.toString(16));  // a

null 和 undefined 没有 toString() 方法。

  1. 原数据类型 + “”(空字符串)
    例如
let num = 111,
    bool = true;
console.log(num + "", bool + "");  // 111 true
console.log(typeof (num + ""), typeof (bool + ""));  // String String
  1. String() 函数
    此函数与 toString() 方法的区别为:当值为 null 或 undefined 时,会返回 “null” 和 “undefined” 。此区别也适用于 方法二 和 toString() 方法的区别。例如:
console.log(undefined + "");  // undefined
console.log(typeof (undefined + ""));  //  String
console.log(null + "");  // null
console.log(typeof (null + ""));  //  String

console.log(String(undefined));  // undefined
console.log(typeof String(undefined + ""));  //  String
console.log(String(null));  // null
console.log(typeof String(null + ""));  //  String

(3)模板字面量:

ES6 新增使用模板字面量定义字符串的能力。例如:

let str1 = 'first\nsecond';
console.log(str1);
// first
// second

let str2 = `first
second`;
console.log(str2);
// first
// second

如上,str1 使用了 ”\n“ 转义字符定义了一个可以换行的字符串,而 str2 使用反引号 (``)+ 回车键,即可实现与 str1相同的效果。回车符 “\n” 在 str2 中也占有位置。

console.log(str2.substring(5, 6) === '\n');  // true

因为模板字面量可以直接定义多行的字符串,因此,也很方便用来定义 HTML 模板。如:

let html = `
<div>
    <a href='#'>
        hello world!
    </a>
</div>`;

(4)字符串插值

let num = 1;
// 原始插值方式
let result = num + ' + ' + num + ' = 2';
// ES6 新增插值方式
let result1 = `${ num } + ${ num } = 2`;
console.log(result);  // 1 + 1 = 2
console.log(result1);  // 1 + 1 = 2

插值表达式中也能调用函数和方法:

function test(word) {
    return `${ word[0].toUpperCase() }${ word.slice(1) }`;
    // 先将 word 的首字母大写,然后插入 word 删去首字母的剩下部分
}
console.log(`${ test('hellow')} , ${ test('world') } !`);  // Hellow , World !

插值表达式也能插入自己之前的值。

let value = '';
function test() {
    value = `${ value }abc`;
    console.log(value);
}
test();  // abc
test();  // abcabc
test();  // abcabcabc

(5)模板字面量标签函数

标签函数本身是一个常规函数,通过前缀到模板字面量来应用自定义行为。如:

let a = 6,
    b = 9;
function simpleTag(String, aValue, bValue, sum) {
    console.log(String);
    console.log(aValue);
    console.log(bValue);
    console.log(sum);
    return `foobar`;
}
let untag = `${ a } + ${ b } = ${ a + b }`;
// console.log(untag);  // 6 + 9 = 15
// console.log(simpleTag(untag));
// 6 + 9 = 15
// undefined
// undefined
// undefined
console.log(simpleTag`${ a } + ${ b } = ${ a + b }`)
// ["", " + ", " = ", ""]
// 6  console.log(String)的输出
// 9  console.log(aValue)的输出
// 15  console.log(sum)的输出
// foobar  return `foobar`的输出

使用剩余操作符(三个点:…):
剩余操作符

let a = 6,
    b = 9;
function zipTag(string, ...exp) {
//     exp.map((e, i) =>{
//         console.log(e, i)
//     })
    return string[0] + exp.map((e, i) => `${ e }${ string[i + 1] }`).join('');
}
console.log(zipTag`${ a } + ${ b } = ${ a + b }`);  // 6 + 9 = 15

(6)获取原始字符串

使用 String.raw 来获取原始的模板字面量内容。

console.log(`\u00A9`);  // ©
console.log(String.raw`\u00A9`);  // \u00A9

实际的换行符无法获取。如:

console.log(String.raw`firsr\nsecond`);  // firsr\nsecond
console.log(String.raw`firsr
second`);
// first
// second
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值