原型原型链

257 阅读3分钟

theme: channing-cyan highlight: atelier-dune-dark

这是我参与8月更文挑战的第25天,活动详情查看:8月更文挑战

原型原型链

  • 每一个函数(自定义类,内置类,普通函数,除es6箭头函数外)都有一个内置的属性prototype 原型属性,这个属性值是一个对象(浏览器内置开辟的堆),在这个对象中存储的就是当前类的公共属性和方法。
  • 在prototype 这个对象中,内置一个constrctor构造函数,属性值就是当前类本身
  • 每一个对象(普通对象/数组对象/实例也是对象/原型对象/函数也是对象)都有一个内置属性:proto (原型链属性),属性值是当前实例所属类的prototype
  • 函数的三种角色 普通函数,构造函数(类),普通对象。所有函数都是Function 类的一个实例
  • Function.prototype === Function.proto; true Function作为一个函数是自己类的实例
  • Object.proto.proto = Object.prototype; true
  • Object.proto == Function.prototype true

Function.prototype 本质是一个函数,是一个匿名函数,但是处理机制是按照函数

  • 原型链机制 :调用当前实例对象的某个属性(成员访问)先看自己私有属性中是否存在,存在调用的就是自己私有的,不存在,则默认按照__proto__ 找所属类的prototype上的共有属性和方法,如果还没有,再基于prototype的__proto__继续向上查找,知道找到Object.prototype为止

函数才有prototype 对象只有__proto__

每一个函数包含内置类都是Function的一个实例,所以他们的__proto__一定指向Function.prototype

每一个对象(包含原型对象等)都是Object 的实例,多以他们基于__proto__一定能找到Object.prototype

  • Object 内置类是所有对象(实例)的基类(最底层)所有在Object.prototype.proto == null,如果不等于null,最后还是指向自己,没有实际的意义了,所以赋值为null;
  • f1.xxx 先找自己的私有属性(是私有的,则获取的是私有的)如果私有的属性中没有,则基于__proto__ 找所属类的原型上的公有的属性和方法,再没有,基于基于原型的__proto__ 向上查找,直到找到Object.prototype 为止, 这种基于__proto__ 向上查找的机制,被称为“原型链查找机制”
  • f1.proto.say() 跳过私有直接找原型上的属性方法

重构原型链指向

  1. 如果在重定向之前,在原型上设置了一些属性和方法,重定向之后,之前的属性和方法都会消失 fun.prototype = Object.assign(fun.prototype,{})

    Object.assign 方法的第一个参数是目标对象,后面的参数都是源对象。

    注意:如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性覆盖前面的属性。

  const target = {a:1, b:1};

  const source1 = {b:2,c:2}

  const source2 = {c:3}

      Object.assign(target, source1, source2);

    target   // {a:1,b:2,c:3}
  1. 重定向之后的原型是没有constructor

基于内置类的原型扩展方法

向内置类的原型上扩展方法,存在的细节知识点 1.为了防止自己设定的方法覆盖内置的方法,我们设置的方法名加前缀 2.优势,使用起来方便,和内置方法类似,直接让实例调用即可 3.方法中的this一般就是当前要操作的实例(也就不需要基于形参传递传递实例进来了) 4.缺点

Array.prototype.myunique = function myunique(){
    let newArr = [...new Set(this)];
    let newArr = Array.from(new Set(this));
    return newArr;
}
let arr = [1,2,1,2,1,2,12,12,12,1];
arr.myunique();