JS基础(数据类型和变量)

JS 有哪些数据类型,如何判断这些数据类型 ?

7种基本数据类型:string, number, boolean, null, undefined, symbol,bigInt
1种引用数据类型:Object 对象:Array(数组)、Function(函数)、Date(时间)等

JS 检测数据类型的 4 种方式

1.typeof:返回值类型为字符串类型;

  • 判断基本数据类型时,除null输出结果为’object’,其他类型判断正确
  • 判断引用数据类型时,除了判断函数会输出’function’,其它都输出‘object’,不能区分引用数据类型

2.instanceof:判断两个对象是否属于实例关系,通过这种关系来判断对象是否属于某一类型;

  • 准确判断引用数据类型,检测构造函数的prototype属性是否在某个实例对象的原型链上
obj1 instance obj2; // 判断obj1 是否为obj2的实例

3.constructor:当一个函数F被定义时,js引擎会为F添加prototype原型,在prototype上添加一个constructor属性,并让其指向F的引用

4.Object.prototype.toString.call()

  • toString() 是Object的原型方法,调用返回当前对象的[object type],type是对象的类型
  • Object对象,调用toString()能返回[object Object]
  • Object.prototype.toString.call(‘’) // [object String]

number 类型表示整数的最大范围

-2^53 —— 2^53

什么是变量提升 ?

包括变量和函数在内的所有声明都会在任何代码被执行前首先被处理,这种现象称为提升
但只有声明本身会被提升,而赋值或其他运行逻辑会留在原地
javascript并不是严格的自上而下执行的语言

1.JavaScript的变量提升是针对var的,而let和const不存在变量提升这一特性
2.通过var定义的变量,在定义语句之前就可以访问到 值:undefined
3.变量提升就是变量会被提升到作用域的最顶上去,也就是该变量不管是在作用域的哪个地方声明的,都会提升到作用域的最顶上去

a = 2;
var a;
console.log(a);

typeof(NaN) 返回什么 ?

返回结果就是 number
NaN === NaN 结果为 false
如何判断一个变量的值是 NaN ?
var a = "我" - "你";
isNaN(a) && typeof a === "number";

typeof(null) 为什么返回的是 'object'

  • typeof(null) = object 是 JS 在诞生设计之初留下的历史遗留 BUG 问题
  • 在 JS 中进行数据底层存储的时候是用二进制存储的,它的前三位是代表存储的数据类型,而 000 是代表 object 类型也就是引用类型的数据
  • null 正好全是 0,所以它巧妙的符合 object 类型的存储格式,所以在 typeof 检测的时候,它才会输出 object

null 和 undefined的区别 ?

undefined(未定义):当一个变量被定义(声明)但并没有赋值时,他的初始值就是 undefined
null(空):表示对一个空对象的引用

  • 当一个变量定好之后,未来是用来保存对象的引用时,我们可以给他赋初始值为 null
  • 当一个对象使用完,需要对其进行释放内存时,可以将其值设置 null (js 会自动垃圾回收)

相同点:

  • undefined 和 null 都是基本数据类型,保存栈中
  • undefined 和 null 转换为 boolean 布尔值都为 false

不同点:
两者转换为数字类型时,其值不一样
Number(undefined); //NaN
Number(null); //0

特殊点:
undefined == null; //true
console.log([] == false) // true

  • [] 转换成字符串是'' ,然后'' 转换成数值是 0
  • false 转换成数值是 0 所以最后比较的值是 0==0 ,结果为 true
if ([]) {
 alert("能弹出吗?"); // 可以弹出弹窗
}

== 和 === 的区别?

== 在比较类型不同的变量时,如果两侧的数据类型不同,则会按以下规则进行相应的隐式类型做类型转换

  • 对象 --> 字符串 --> 数值
  • 布尔值 --> 数值
    转换后,再比较两边的值是否相等,值相等返回 true,不等返回 false;

=== 在比较时,会比较值和类型两个。只要两边值的类型不相等就返回 false

NaN === NaN; // false NaN和任何数据都不相等,包括自身
[] == []; // false 比较的是地址
{} == {}; // false 比较的是地址
undefined == null; // true; 特殊情况,记下

const、let、var 区别

变量提升和暂时性死区:var 存在变量提升,let 和 const 不存在变量提升,所以 let 和 const 会存在暂时性死区
块级作用域:var 不存在块级作用域,let 和 const 存在块级作用域
重复声明:var 允许重复声明变量,let 和 const 在同一作用域下不允许重复声明变量
修改变量:var 和 let 声明的变量可以修改,const 是不可以的
使用:const 用来声明常量,引用类型值。其它情况推荐用 let ,避免用 var

const 定义的值一定是不能改变的吗

const 实际上保证的,并不是变量的值不得改动,而是变量指向的那个栈内存地址所保存的数据不得改动
对于简单类型的数据(数值、字符串、布尔值)值就保存在变量指向的那个栈内存地址,因此等同于常量
引用类型的数据(主要是对象和数组)变量指向的栈内存地址,保存的只是一个指向实际数据的指针
const 只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了
若 const 声明的是一个引用类型的变量,其引用类型的结构是可以发生改变的

const 声明了数组,还能 push 元素吗,为什么?

可以,
栈内存中的地址,只是一个指向实际数据的指针。指针指向堆内存中保存的数据
const 只能保证栈内存中的地址不变,但是堆内存中的数据如何改变是没有办法控制的
push 方法相当于是改变了堆内存中的数据结构

JS 获取字符串的第 N 个字符

  • 字符串函数直接截取:str.substr(1,1); str.substring(1,2); str.slice(1,2)
    str.substring(1,2); str.slice(1,2)表示截取的起始和结束位置
    但是slice入参允许为负,表示截取str的倒数第几个字符
    str.substr表示截取的起始位置和截取的长度
  • 字符串可遍历性:for…of
  • Es6的解构赋值
  • 正则匹配

const 声明生成对象的时候,如何使其不可更改

const 声明的对象只保存其对象的引用地址,只要地址不变,就不会出错,使用Object.freeze(obj)冻结obj,可使内部属性不可变,局限是若属性是对象,该对象内属性还能改变,要求不可变可使用递归一层层冻结

以下这两种方式的区别 ?typeof 判断

const str1 = "abc";    
typeof(str1)  // 'string'
const str2 = new String("abc");
typeof(str2)     // 'object'
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容