原型,万物皆对象,原型链,判断数据类型

98 阅读3分钟

1.原型

创建一个函数(非箭头函数),就会按照特定的规则为这个函数创建一个 prototype 属性(指向原型对
象)。默认情况下,所有原型对象自动获得一个名为 constructor 的属性,指回与之关联的构造函数。
在自定义构造函数时,原型对象默认只会获得 constructor 属性,其他的所有方法都继承自Object。每
次调用构造函数创建一个新实例,这个实例的内部[[Prototype]]指针就会被赋值为构造函数的原型对
象。脚本中没有访问这个[[Prototype]]特性的标准方式,但 Firefox、Safari 和 Chrome会在每个对象
上暴露`__proto__`属性,通过这个属性可以访问对象的原型

2.万物皆对象

 JS 中, 万物都可以都可以称为对象
     对象: 
           含义1: 一种数据格式 {key: value, key2: value2}
           含义2: 某一类事务的实例 (某一类内容中的 真实个体)
           const arr = [1, 2, 3]
           const arr1 = [1, 2, 3, 4]
           const arr2 = [1, 2]
           这个 arr1 就是 Array 这一类内容中的 某一个 真实个体, 数组也可以算作一个对象
           (Array 这一类事务中的一个个体)
     
           const fn = () => {console.log(1)}
           const fn2 = () => {console.log(2)}
           const fn3 = () => {console.log(3)}
           
           函数也是一个对象(属于 Function 这一类事务中的一个个体) 
           如果一个数据 [] 那么他就是Array 这个对象中的某一个个体
           如果一个数据 {} 那么他就是Object 这个对象中的某一个个体
           如果一个数据 function(){}   那么他就是 Function 这个对象中的某一个个体
           

3.原型链

  重温一下构造函数、原型和实例的关系:每个构造函数都有一个prototype指向原型对象,原型对象有
  一个constructor属性指回构造函数,而实例有一个内部指针指向原型。如果原型是另一个类型的实例
  呢?那就意味着这个原型本身有一个内部指针指向另一个原型,相应的另一个原型也有一个指针指向另
  一个构造函数。这样就在实例和原型之间构造了一条原型链。这就是原型链的基本构想。
  
  function SuperType() {   this.property = true; } 
  SuperType.prototype.getSuperValue = function () {   return this.property; };
  function SubType() {   this.subproperty = false; } // 继承 SuperType  
  SubType.prototype = new SuperType(); SubType.prototype.getSubValue = function () { 
  return this.subproperty; }; let instance = new SubType(); 
  console.log(instance.getSuperValue()); // true
  
  SuperTypeSubType这两个类型分别定义了一个属性和一个方法。这两个类型的主要区别是SubType
  通过创建 SuperType 的实例并将其赋值给自己的原型 SubTtype. prototype 实现了对 SuperType 
  的继承。这个赋值重写了 SubType 最初的原型,将其替换为SuperType 的实例。这意味着 SuperType 
  实例可以访问的所有属性和方法也会存在于 SubType. prototype。这样实现继承之后,代码紧接着又
  给 SubType.prototype,也就是这个 SuperType 的实例添加了一个新方法。最后又创建了 SubType 
  的实例并调用了它继承的 getSuperValue()方法。
  

4.判断数据类型

   判断数据类型
           1. typeof   判断基本数据类型
      
           2. constructor 可以判断 当前数据的 构造函数 是谁
                   问题1: 能够判断引用数据类型
                           但是! 这个属性其实就是对象内的一个属性
                           我们可以拿到这个对象, 然后修改他的属性值
                   问题2: 不能判断 undefinednull
      
           3. instanceof 可以判断 左边的构造函数是否等于右边的构造函数
               语法: 检测的数据 instanceof 构造函数
               问题: 不能判断 undefinednull
      
           4. Object.prototype.toString.call(要判断的数据结构)
                   Object 这个构造函数的 原型内部 有一个 toString 的方法
                   这个方法能够帮我们将数据结构转为字符串的形式    '[object 数据结构]'
      
               我们在使用的时候 如果需要判断其他数据类型, 需要使用 .call这个方法改变内部 this 指向
      
               这个方法任何数据类型都能准确判断(推荐使用)