JavaScript那些事--✪--原型链类、new和instanceof原理

创建对象几种方法

四种创建方法,为面向对象打下基础

原型链类(原型、构造函数、实例、原型链)

构造函数

  • 定义把函数放在new操作符后面的函数叫构造函数。

    任何函数,只要通过new操作符调用,就是构造函数,如果不是new调用的,则和普通函数不会有什么两样。

  • 一般写构造函数的名字时,首字母是大写
  • 所有的引用类型都是有构造函数
var a = {} // 其实是var a =new Object()的语法糖
var a = [] // 其实是var a =new Array()的语法糖
function Foo(){...} // 其实是var Foo = new Function(){....}

原型、实例

首先看下面代码:

  function Person(name) {
    this.name = name
  }
  var m = new Person('我爱罗')
  • new Person创建了一个实例m【就是一个具体化的产品】。
  • 声明函数Person的时候,JS引擎会给函数自动增加一个属性prototype初始化为空对象,也就是原型对象即原型。
    在这里插入图片描述
    问:那我怎么知道这个原型对象是被哪个构造函数引用?
    答:实际上原型对象上有个构造器(constructor),构造器会默认为你声明的函数。
    在这里插入图片描述

原型链

实例对象往上找构造这个实例的原型对象,然后再往上找原型对象之上的原型对象,以此类推一直找到Object.prototype(原型链顶端)

  Person.prototype.say = function () {
    console.log('hi')
  }
  var m1 = new Person('李洛克')

在这里插入图片描述
如果实例中没有这个方法则会通过__proto__ 到原型对象上找,如果还是没有再往上,以此类推。如果到Object.prototype还是没有找到,则报错没定义这个方法。
在这里插入图片描述
这个里面也可以看到构造函数中会增加了很多方法和属性,当我们创建多个实例的时候,可以避免每个都copy一份,而是存在他们共同的地方-原型对象

温馨提示: 创建对象使用Object.create方法为什么返回时空?
因为Object.create是把参数作为一个新对象的原型对象赋给实例,实例本身不具备属性,只能通过原型链查找。

原型链类总结:

在这里插入图片描述
原型规则:

  1. 所有引用类型都具备对象特性,即可自由扩展属性。
var obj = {};obj.a=100
var arr = []; arr.a =100
function fn() {} 
fn.a=100
  1. 所有引用类型都有一个__proto__(隐式类型)属性,属性是一个普通对象。
    在这里插入图片描述
  2. 所有函数都有一个prototype(显式类型)属性,属性值是一个普通对象。
  3. 所有引用类型的__proto__属性值指向(完全等于)它的构造函数prototype属性值
    在这里插入图片描述
  4. 当试图得到一个对象的属性或方法时,如果本身没有,则会从它的__proto__寻找,一直找到原型链顶点。

instanceof原理

在这里插入图片描述
继续拿这个为例子

  function Person(name) {
    this.name = name
  }
  var m = new Person('我爱罗')
  console.log(m instanceof Person) // true

m instanceof Person原理是,m的__proto__一层层往上,能否对应到Person.prototype,找到则返回true。
这种判断也不时很严谨因为,m instanceof Object也是true。最严谨的方法是用构造器(constructor)
在这里插入图片描述

new 运算符

  1. 一个新对象被创建,它继承这个函数的原型对象(foo.prototype)。
  2. 构造函数foo被执行。执行的时候,相应的传参会被传入,同时上下文(this)会被指定为这个新实例。new foo 等同与new foo(),只能用在不传递任何参数的情况。
  3. 如果构造函数返回了一个对象,那么这个对象会取代整个new出来的结果。如果构造函数没有返回对象,那么new出来的结果为步骤1创建的对象。
var new2 = function (func) {
    var o = Object.create(func.prototype)
    var k = func.call(o)
    if (typeof k === 'object') {
      return k
    } else {
      return o
    }
  }
 var m2 = new2(Person)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章