JavaScript 数据类型_红宝书盖楼_2

359 阅读9分钟

JavaScript语法

ECMAscript 的语法大量借鉴了C及其他类C语言的语法;

区分大小写(变量、函数名、操作符)

标识符:就是指变量、函数、属性的名字,或者函数的参数。

标识符定义规则第一个字符必须是一个字母下划线、或一个美元符号,其他字符可以使字母、下划线、美元符$或数字;

不能把关键字、保留字、true/false和null作为标识符

采用驼峰大小写格式,首字母小写,剩下单词的首字母大写。

严格模式 "use strict" 告诉编译器切换到严格模式

1、变量

变量是松散型的,就是可以用来保存任何类型的数据。变量仅仅是一个用于保存值的占位符

变量声明的三种方式:

  • var 可以用来声明全局变量,也可以声明局部变量,定义的变量的时候,若没有初始化,不报错,会输出undefined。其值之后可以修改。
    • 全局变量:在函数外定义的变量;(注意:若没有使用关键字声明的变量,默认为全局变量。)作用域是整个代码文件。
    • 局部变量:在函数内定义的变量。作用域是当前的函数内部。
  • let 声明块级变量,即局部变量,函数内部使用let定义后,对函数外部无影响。
  • const 用于声明常量,也具有块级作用域 const PI=3.14;且定义的变量不可以修改,而且必须初始化

2、数据类型

ES5的时候,我们认知的数据类型确实是 6种:NumberStringBooleanUndefinedNullObject

ES6 中新增了一种 Symbol 。这种类型的对象永不相等,即始创建的时候传入相同的值,可以解决属性名冲突的问题,做为标记。

谷歌67版本中还出现了一种 bigInt。是指安全存储、操作大整数。(但是很多人不把这个做为一个类型)相关处理大整数的库 bignumber.js

参阅资料来源:JS最新基本数据类型:BigInt

3、typeof 操作符,检测给定变量的数据类型
Type Result
Undefined "undefined"
Null "object" (see below)
Boolean "boolean"
Number "number"
BigInt (new in ECMAScript 2020) "bigint"
String "string"
Symbol (new in ECMAScript 2015) "symbol"
Function object (implements [[Call]] in ECMA-262 terms) "function"
Any other object "object"

typeof详解

typeof运算符用于判断对象的类型,但是对于一些创建的对象,它们都会返回'object',有时我们需要判断该实例是否为某个对象的实例,那么这个时候需要用到instanceof运算符,后续记录instanceof运算符的相关用法。

instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链

3.1 Undefined类型

只有一个值的数据类型,值即为undefined。

变量未经初始化的值默认是undefined值。

对未经初始化的变量执行typeof 会返回undefined,对未声明的变量执行typeof也会返回undefined。

undefined表示"缺少值",就是此处应该有一个值,但是还没有定义。

3.2 Null 类型

第二个只有一个值的数据类型,值为null。

null值表示一个空对象指针。这是typeof 返回object的原因。

如果定义的变量准备用于保存对象,一般将变量的初始化值为null。

null表示"没有对象",即该处不应该有值

undefined == null // true
undefined === null // false
Number(null) // 0
Number(undefined) // NaN
3.3 Number 类型

数值的转换:

非数值转数值:Number()、parseInt()、parseFloat()

parseFloat()是将字符串转换为浮点数,并返回字符串中的数字,直到它到达不是数字部分。

parseInt()可以将任何进制的字符串转换成整数。

// 面试题
[1,2,3].map(parseInt)的结果是什么?
// 首先map的时候,里面传一个函数,那么map会默认给函数传两个参数:value,index,那么这两个参数传给parseInt的时候,代表的意思就不一样了,parseInt函数接收两个参数第一个是要转换的字符串,第二个是代表的按几进制进行转换,注意:是按几进制进行转换,而不是转成了几进制。
// [1,2,3].map(parseInt)
第一次循环,传给parseInt(1,0),把10进制转换,0默认表示10进制,然后输出1第二次循环,传给parseInt(2,1),把21进制转换,引擎懵逼了,1进制中根本不可能出现2这个数字好吗?我咋给你解析,无法解析,给了个NaN第三次循环,传给parseInt(3,2),把32进制转换,引擎又懵逼了,啥玩意儿?2进制中根本不可能出现3这个数字好吗?我咋给你解析,无法解析,又给了个NaN
3.4 String 类型

由0个或多个16位Unicode字符组成的字符序列,称为字符串。

字符字面量:转义字符 \n 换行 \t 制表 \r 回车

转换字符串:

  1. toString(x) null和undefined 没有这个方法.;x参数为转换基数。默认是10
  2. String() 在不知道要转换的值不是null和undefined时,用String()
  3. +"字符串"
3.5 Object 类型

对象其实就是一组数据和功能的集合。

object实列对象都具有下列属性和方法:

  • constructor:保存着用于创建当前对象的函数,如构造函数就是Object();
  • hasOwnProperty:检查给定的属性是否在当前实列中存在,而不是在实列的原型中存在;
  • isPrototypeof(object): 检查传入的对象是否是当前对象的原型
  • toLocaleString(): 返回对象的字符串表示,该字符串和执行环境的地区对应
  • toString():返回对象的字符串表示
  • valueOf():返回对象的字符串、数值、布尔值表示

Object构造函数,会根据给定的参数创建对象,具体有以下情况:

  1. 如果给定值是 nullundefined,将会创建并返回一个空对象
  2. 如果传进去的是一个基本类型的值,则会构造其包装类型的对象
  3. 如果传进去的是引用类型的值,仍然会返回这个值,经他们复制的变量保有和源对象相同的引用地址

4.操作符

4.1 一元操作符

前置型 ++ -- 执行前置递增和递减操作时,变量的值都是在语句被求值前改变。求值前,先执行

后置型 ++ -- 执行后置递增和递减操作时,变量的值都是在语句被求值后改变,求值后,再执行

4.2 布尔操作符

非 与 或

逻辑非 !

  • 将一个值转为与其对应的布尔值,同时使用两个逻辑非!!实际会模拟Boolean()转型函数的行为。第一个!返回一个布尔值,第二!对返回的布尔值进行求反操作。

逻辑与 &&

  • 两个同时为true才为true
  • 第一个操作数能够觉得结果,就不会对第二个操作数操作求值
  • 如果第一个操作数是flase,则无论第二个操作数是什么值,都不会返回true
  • 两个值都是对象,则返回第二个对象

逻辑或 ||

  • 只要其中一个为true,则为true
  • 如果第一个操作数的求值结果为true,就不会对第二个操作数求值
4.3 相等操作符

相等和不相等 == != 都会先转换操作数 强制转换,然后比较他们的相等性

全等和不全等 === == 全等是在两个操作数没转换就相等的情况下返回true

null == undefined // true

null === undefined // false 是不同的类型


5、语句

if

do-while

while

for

for-in

break continue 虽然也是立即退出循环,但退出循环后会从循环的顶部继续执行

Switch1


6、函数

通过函数可以封装任意多条语句,可以在任何地方,任何时候进行调用执行

function 关键字声明,后跟一组参数以及函数体

函数本身不运行,必须调用才运行。

6.1 参数arguments 对象

arguments 对象与数组类似的对象。

arguments.length 属性可以获知有多少个参数传递给了函数

2020_07_21_7NfHHY
2020_07_21_7NfHHY

小结:

1.JS 的数据类型有几种?

8种。NumberStringBooleanNullUndefinedObjectSymbolBigInt

2.JS的基本类型和引用类型有哪些呢?

​ 基本类型:除Object。 String、Number、boolean、null、undefined。

引用类型:Object。里面包含的 function、Array、Date。

​ NaN 是 Number 中的一种,非Number 。typeof NaN // number

3.null 和 undefined 有什么区别?

​ null表示"没有对象",即该处不应该有值。

   undefined表示"缺少值",就是此处应该有一个值,但是还没有定义

简单值例如字符串和数字比较值就可以了

对象比较的时候比较的是引用(就是内存地址)

参考资料来源:如何对比JS中两个对象是否相等

    function deepCompare(x, y) {
        var i, l, leftChain, rightChain;

        function compare2Objects(x, y) {
            var p;

            // remember that NaN === NaN returns false
            // and isNaN(undefined) returns true
            if (isNaN(x) && isNaN(y) && typeof x === 'number' && typeof y === 'number') {
                return true;
            }

            // Compare primitives and functions.     
            // Check if both arguments link to the same object.
            // Especially useful on the step where we compare prototypes
            if (x === y) {
                return true;
            }

            // Works in case when functions are created in constructor.
            // Comparing dates is a common scenario. Another built-ins?
            // We can even handle functions passed across iframes
            if ((typeof x === 'function' && typeof y === 'function') ||
                (x instanceof Date && y instanceof Date) ||
                (x instanceof RegExp && y instanceof RegExp) ||
                (x instanceof String && y instanceof String) ||
                (x instanceof Number && y instanceof Number)) {
                return x.toString() === y.toString();
            }

            // At last checking prototypes as good as we can
            if (!(x instanceof Object && y instanceof Object)) {
                return false;
            }

            if (x.isPrototypeOf(y) || y.isPrototypeOf(x)) {
                return false;
            }

            if (x.constructor !== y.constructor) {
                return false;
            }

            if (x.prototype !== y.prototype) {
                return false;
            }

            // Check for infinitive linking loops
            if (leftChain.indexOf(x) > -1 || rightChain.indexOf(y) > -1) {
                return false;
            }

            // Quick checking of one object being a subset of another.
            // todo: cache the structure of arguments[0] for performance
            for (p in y) {
                if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) {
                    return false;
                } else if (typeof y[p] !== typeof x[p]) {
                    return false;
                }
            }

            for (p in x) {
                if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) {
                    return false;
                } else if (typeof y[p] !== typeof x[p]) {
                    return false;
                }

                switch (typeof(x[p])) {
                    case 'object':
                    case 'function':

                        leftChain.push(x);
                        rightChain.push(y);

                        if (!compare2Objects(x[p], y[p])) {
                            return false;
                        }

                        leftChain.pop();
                        rightChain.pop();
                        break;

                    default:
                        if (x[p] !== y[p]) {
                            return false;
                        }
                        break;
                }
            }

            return true;
        }

        if (arguments.length < 1) {
            return true; //Die silently? Don't know how to handle such case, please help...
            // throw "Need two or more arguments to compare";
        }

        for (i = 1, l = arguments.length; i < l; i++) {

            leftChain = []; //Todo: this can be cached
            rightChain = [];

            if (!compare2Objects(arguments[0], arguments[i])) {
                return false;
            }
        }

        return true;
    }

本文使用 mdnice 排版

文章列表

JavaScript 基本概念

JavaScript 数据类型

JavaScript 基本类型和引用类型

javascript 执行环境和作用域

javascript 垃圾收集机制

javascript 数组