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() 跳过私有直接找原型上的属性方法
重构原型链指向
-
如果在重定向之前,在原型上设置了一些属性和方法,重定向之后,之前的属性和方法都会消失 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}
- 重定向之后的原型是没有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();