前言
原型和原型链是JavaScript中最基础的部分,如果你还没有搞清楚这里,下面这篇文章就带你一起夯实一下基础吧
原型原型链
prototype 原型
prototype是函数的一个属性,值是一个对象
const fn = Function Fn() {};
fn.prototype // fn.prototype 是一个对象 {constructor: f}
每一个函数,都会有一个默认的prototype的属性,是一个对象
__proto__ 属性
是Object的一个属性 也是一个对象
每一个对象,都有一个__proto__的属性,是一个对象
let obj = {age: 3}
obj.__proto__ // {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
对象的__proto__的值是该对象的构造函数的prototype
obj.__proto__ === Object.prototype // true
function Test() {}
let test = new Test();
test.__proto__ === Test.prototype;
// Test.prototype 是一个对象,所以他也有__proto__
Test.prototype.__proto__ === Object.prototype // true
Object.prototype.__proto__ // null 原型链顶层是null
特殊情况
typeof Object // "function"
typeof Function // "function"
const fn = new Function()
fn.__proto__ // ƒ () { [native code] }
Function.prototype // ƒ () { [native code] }
这里fn 怎么也会有proto的属性呢,这里就要说下new 操作符了
在new的时候,new操作符做了下面这几件事情
- 首先创建了一个对象
- 然后将对象的proto 属性设置为了 构造函数的prototype
- 然后将this绑定在创建的对象上
- 若函数没有返回这个对象则返回this
这个时候,我们看到,fn.proto 属性其实等于 Function.prototype
fn.__proto__ === Function.prototype // true
let Test = new Function()
Function._proto_ // ƒ () { [native code] }
Function.prototype // ƒ () { [native code] }
Function._proto_ === Function.prototype // true
Object._proto_ // ƒ () { [native code] }
Object._proto_ === Function.__proto__
Object._proto_ === Function.prototype
原型链
自己本身没有的属性,会顺着自己的--proto-- 属性一直往上找
如果给Test.prototype 中加一个属性。Test.prototype.a = 1; 则。test.__proto__就会多一个a =1 的属性
function Test() {}
let test = new Test();
test.constructor === Test // true
test.a = 1;
Test.prototype.b = 2;
test.b // 2
test.hasOwnProperty('a') // true
test.hasOwnProperty('b') // false
'b' in test // true;
'a' in test // true
如果我们想要只判断自己本身有没有属性。则需要用hasOwnProperty 来判断。
如果判断 属性在不在自身或者自己的原型上,则可以用 in
constructor属性
function Test() {}
let test = new Test();
test.__proto__.constructor === Test // 对象的__proto__里的constructor属性指向他的构造函数
总结
每一个构造函数都有一个prototype的属性,每一个对象都有一个——proto__属性,构造函数实例化出来的对象的--proto-- 指向 构造函数的prototype,实例化出来的--proto--对象中的constructor 属性是他的构造函数,寻找对象的属性的时候会按照--proto--依次向上寻找,构成的链就是原型链。原型链的终点是null
看到这里啦,点个👍吧~
如有错误,还请指出,共同进步~~