原型与原型链

82 阅读2分钟

原型与原型链

谁有__proto__原型链隐式属性

首先先搞清楚谁有__proto__原型链

        let a = new Array()
        let b = new Object()
        let c = new Map()
        let d = new Set()
        let e = new Function()
        console.log(a.__proto__)
        console.log(b.__proto__)
        console.log(c.__proto__)
        console.log(d.__proto__)
        console.log(e.__proto__)

猜猜会输出什么

屏幕截图_20230201_212816.png

首先可以肯定的是这些引用数据类型都有__proto__原型链,但是他们各不相同,具体为哪些不同,我们再来探究一下。

        console.log(a.__proto__ === Array.prototype)
        console.log(b.__proto__ === Object.prototype)
        console.log(c.__proto__ === Map.prototype)
        console.log(d.__proto__ === Set.prototype)
        console.log(e.__proto__ === Function.prototype)

屏幕截图_20230201_213132.png

这些打印都为True,说明什么?首先再new每个实例对象的时候,都会走一遍对应的构造函数,所以他们的父亲其实就是对应的构造函数,比如a是一个数组类型的实例对象,通过new Array而来,所以a的父亲就是Array的原型。

谁有prototype原型属性

那么这些引用类型的对象也会有prototype原型属性吗?

答案是:只有构造函数才有prototype原型属性。

还是有点懵是不是,我们再来看一段代码。

 const Person = function () {
      this.name = "1"
 }
​
  const xiaoming = new Person()
  
  console.log(Person.prototype)
  console.log(xiaoming.prototype)
  console.log(xiaoming.__proto__)
​
  console.log(xiaoming.__proto__ === Person.prototype)

屏幕截图_20230201_213801.png

前三个打印输出印证了只有构造函数才有prototype原型属性,另外也能印证由构造函数new处理的实例对象的__proto__会等于构造函数的prototype属性,可以理解为它的父亲(__proto__)一定是那个构造函数(prototype属性)。那么你能理解实例对象的__proto__和构造函数的prototype属性之间的关系了吗?

然后再来理解一下constructor

    console.log(xiaoming.constructor) 
    /*ƒ () {
        this.name = "1"
        }*/
​
​
    console.log(xiaoming.constructor === Person)
    //true

能看出来就是xiaoming的构造器就是Person,另外constructor构造器是可以改变的,但是改变了即使constructor,这个实例对象的__proto__也不会改变。

     function Man(){
            this.sex="男"
        }
        xiaoming.constructor = Man
        console.log(xiaoming.constructor)
/*    function Man(){
            this.sex="男"
        }*/
​
        console.log(xiaoming.__proto__ === Person.prototype) //true
        console.log(xiaoming.__proto__ === Man.prototype) //false

最后来看看这个整体的原型链

console.log(Person.__proto__ === Function.prototype)
//true
console.log(Array.__proto__ == Function.prototype)
//true
console.log(Map.__proto__ == Function.prototype)
//true
console.log(Set.__proto__ == Function.prototype)
//true
console.log(Object.__proto__=== Function.prototype)
//true
console.log(Function.prototype === Function.__proto__)
//true

可以看成所有引用类型的构造函数的__proto__都是Function.prototype,什么Function就是最顶层的构造函数,最后底层定义Function.prototype等于Function.__proto__

Ending

以上均为个人见解,如果有不正确的地方还望指出,