目录
1、JavaScript有哪些数据类型,它们的区别?
2、基本数据类型和引用数据类型地区别:
3、数据类型检测的方式有哪些:
4、判断数组的方式有那些?
5、null和undefined区别:
6、为什么typeOf null得到object而不是null
7、null == undefined得到true而 null === undefined得到false?
8、instanceOf操作符的实现原理及实现
1、JavaScript有哪些数据类型,它们的区别?
1️⃣:基本数据类型:number、string、boolean、Undefined、NaN、Symbol
2️⃣:引用数据类型:Object、Array、function
基本数据类型:放在内存的栈中
引用类型数据:放在内存的堆中
3️⃣:区别
NaN是JS中的特殊值,表示非数字,他不等于任何值,包括自身,在布尔运算时被当作false,NaN与任何值运算的结果都是NaN
Symbol和BigInt是ES6中新增的数据类型:
- Symbol代表创建独一无二且不可变的数据类型,它主要是为了解决可能出现的全局变量冲突的问题
- BigInt可以安全地存储和操作大整数,即使这个数已经超过Number能狗表示地安全整数范围。
2、基本数据类型和引用数据类型地区别:
1️⃣:基本数据类型是按值访问的,操作保存在变量中的实际的值。
2️⃣:基本数据类型的值是不可变的,变量名只是指向变量的一个指针,变量重新赋值改变的是指针的指向,该变量是不变的。
3️⃣:基本数据类型不可以添加属性和方法,但是引用类型可以。
4️⃣:基本数据类型的赋值是简单赋值,如果从一个变量向另一个变量赋值基本类型的值,会在变量对象上创建一个新值。
变量对象:变量对象是JS中内部的数据结构,用于存储在执行上下文声明的变量和函数
5️⃣: 基本数据类型的比较是值的比较,引用类型的比较是引用的比较
引用类型的比较是比较引用地址,如果有两
个对象即使key和value都相同,但是当用(===)全等符号比较时,返回的是false。
3、数据类型检测的方式有哪些:
1️⃣:typeOf
typeOf对数组、对象、null,function都会判断为object
JS将数组和对象视为对象,将null视为一个特殊的空对象指针。
数组是一种特殊的对象,其键名是以数字为下标的一组有序属性。
2️⃣:instance of
function Foo = {}
let fo = new Foo()
console.log(fo instanceOf Foo) 
instanceof只能判断对象的类型,无法判断基本数据类型。
内部运行机制是判断其原型链中能否找到该类型的原型。
instanceof可以用来测试一个对象在其原型链中是否存在一个构造函数的prototype属性
3️⃣:constructor
constructor有两个作用:
- 是判断数据的类型
- 是对象实例通过constructor对象访问它的构造函数
❗❗ :如果创建一个对象改变它的原型,constructor就不能用来判断数据类型
function Fn(){};
Fn.prototype = new Array();
var f = new Fn();
console.log(f.constructor===Fn); // false
console.log(f.constructor===Array); // true 
4️⃣:Object.prototype.toString.call()
var a = Object.prototype.toString
console.log(a.call(2)) //Number
console.log(a.call(true)) //Boolean 
obj.toString()的结果和Object.prototype.toString.call(obj)的结果不一样:
原因:toString是Object的原型方法,而Array、function等类型作为Object的实例,都重写了toString方法。不同的对象类型调用toStrin()方法时,调用的是对应的重写之后的toString方法,而不会去调用Object上原型toString方法。
4、判断数组的方式有那些?
1️⃣:通过Object.prototype.toString.call()做判断
Object.prototype.toString.apply/call(变量) === [OBJECT ARRAY]
2️⃣:通过原型链做判断
const ary = new Array()
console.log(ary.__proto__ === Array.prototype); 
3️⃣:通过ES6的Array.isArray()方法做判断
const ary = new Array()
console.log(Array.isArray(ary)); 
4️⃣:通过instanceOf做判断
const ary = new Array()
console.log(obj instanceof Array); 
5️⃣:通过Array.prototype.isPrototypeOf做判断
const ary = new Array()
console.log(Array.prototype.isPrototypeOf(ary)); 
5、null和undefined区别:
🔰undefined:
- 使用var或let声明了变量但没有初始化
 - 访问对象上不存在的属性
 - 未声明的变量使用typeof返回的依旧是undefined
 - 函数定义了形参,但没有传递形参
 - 使用函数的返回值,当没有return操作符时,就默认返回一个原始的状态,就是undefined,表明函数的返回值未被定义。
 - 使用void对表达式求值:void操作符对任何表达式求值都返回undefined
 
🔰:null代表空对象指针
区别:
- 不要对一个变量显示的赋值undefined,当需要变量需要保存对象,直接赋值为null即可
- 当对这两种类型使用typeOf进行判断时,null会返回object,undefined依然返回的是undefined。
- undefined是为了明确空对象指针和未初始化变量的区别
6、为什么typeOf null得到object而不是null
因为JS中不同对象在底层都表示为二进制,而JS中会把二进制的前三位都为0判断为object类型,而null的二进制表示全都是0,自然前三位也是0, 所以执行typeof时会返回object。
7、null == undefined得到true而 null === undefined得到false?
要比较null和undefined相等性之前,不能将null和undefined转化为其他类型值再比较,但null==undefined得到的是true。是因为undefined值是派生自null值。ECMA规定对二者进行相等性测试返回ture。
8、instanceOf操作符的实现原理及实现
instanceOf用于判断构造函数的prototype属性是否出现在对象的原型链上:
 fo  instanceOf Foo 
左边fo是右边Foo构造函数的实例化对象
function myInstanceOf(left,right){
    //获取对象的原型对象
   let proto = Object.getPrototypeOf(left)
   //获取构造函数的prototype属性
   let prototype = right.prototype
   //判断构造函数的prototype对象是否在对象的原型链上
   while(true){
    if(!proto) return false
    if(proto === prototype) return true
   //如果么有找到,就继续从原型上找
    proto = Object.getPrototypeOf(proto)
    }
}
     

🔰知识点补充:
1. getPrototypeOf():
Object.getPrototypeOf() 方法返回的为对象,该对象就是传入对象的原型对象
const prototype1 = {};
const object1 = Object.create(prototype1); //创建新对象
console.log(Object.getPrototypeOf(object1) === prototype1); 
💨 Object.getPrototypeOf()可以方便的取得原型对象上自定义属性的值
function Person() { }
        Person.prototype.name = 'CMY'
        let newPerson = new Person()
        console.log(Object.getPrototypeOf(newPerson).name); 输出为CMY 
2. setPrototypeOf()方法:
语法:
Object.setPrototypeOf(obj, prototype) 
参数:
- obj :要设置其原型的对象。
- prototype:该对象的新原型(一个对象或 null)。
   let biped = {numLegs:2}
        let person = {name:'CMY'}
        Object.setPrototypeOf(person,biped)
        console.log(Object.getPrototypeOf(person) === biped); 输出为true 
3 原型对象,原型
⏩:原型对象就是prototype,而prototype是一个对象,所以称为原型对象
⏩:对象的原型,指的就是该对象的prototype属性
⏩:只要创建一个函数,就会按照特定的规则为这个函数创建一个prototype属性。默认情况下,所有的原型对象自动获得一个constructor的属性
  function Person() { }
        console.log(Person.prototype); 
输出的结果:
⏩:正常的原型链都会终止于Object的原型对象,Object原型的原型是NULL

⏩:构造函数的实例是通过__proto__链找到原型对象
 function Person() { }
        let newPerson = new Person()
        console.log(newPerson.__proto__); 
构造函数通过prototype属性链接到原型对象。
⏩:实例与构造函数没有直接的关系,与构造函数的原型对象有直接联系
 function Person() { }
        let newPerson = new Person()
        console.log(newPerson.__proto__ === Person.prototype); 输出true 
                





![[oeasy]python0050_动态类型_静态类型_编译_运行](https://img-blog.csdnimg.cn/img_convert/0ec95436f367102609e79deec2ee1b5a.png)








![[JAVA EE]创建Servlet——继承HttpServlet类笔记2](https://img-blog.csdnimg.cn/63dec33eb8fb43078f994eaccca3c93f.png)
![[前端基础]websocket协议](https://img-blog.csdnimg.cn/8d13bc87c4854523bf94b119db37b7e3.png)


