JavaScript的原型链的理解

JavaScript的原型链算是JS比较难的一个点了。断断续续学习了一段时间,进过自己的思考,好像总结了一套自己的理解。

原型链总图:


截屏2022-05-19 下午8.49.42.png

Js是通过对象创建对象,所以每个对象都有它的对象原型。

一、函数对象:

function Person() {

}

let UserMan = new Function();

Person和UserMan都是函数对象,他们的proto都指向函数原型对象
console.log(UserMan.proto==Person.proto) //true

二、数组对象

let arr = new Array();

arr为数组对象,它的proto都指向数组原型对象。

三、简单对象(可理解为字典或结构体)

1、通过Object创建对象

let obj = new Object();

obj为简单对象
console.log(obj.proto=={}.proto) //true

2、直接字面量创建对象

let user = {
    name : 'han',
    introduce : function(){ console.log(this.name); }
};

user为简单对象
console.log(user.proto=={}.proto) //true
简单对象没有特定的原型对象,它的proto直接指向顶层原型对象了。

3、通过Object.create创建对象

let maleUser = Object.create(user);
maleUser.__proto__ —> user

let person = {name:"alex",age:"19"};
let man = Object.create(person);
man.name = "johnny";
console.log(man.name);      //johnny
console.log(man.__proto__.name);        //Alex

以user作为原型,创建一个对象。
通过Object.create创建的对象,就相当于copy了一份原型对象。

4、通过函数对象创建对象

function Person() {
}
let person = new Person();

四、prototype

理顺了上面各种对象后,下面开始引入prototype属性。它是函数对象特有的一个属性。
为什么函数对象需要这样一个属性呢?
我们通过Person函数对象创建一个对象person
let person = new Person();
person.name = “abc”;

这里的person明显就是简单对象,就是说这里通过了函数对象创建出来了简单对象。我们知道,每个对象肯定有原型,那person的原型是什么呢,肯定不是创建它的函数对象,所以函数对象里面必须有一个属性存储创建的对象的原型。这里就通过prototype属性来存储创建对象的原型。
console.log(person.proto.proto=={}.proto) //true

回看上面的以user作为原型,创建一个对象。
那么person应该是以{}作为原型,创建的一个对象。
相当于:

let per = {};
let person = Object.create(per);
person.__proto__ —> per

拓展
更泛的理解是,通过new方式创建对象的函数对象或包装类,都是用prototype存储其对象真正的原型。
Function函数构造器new出来的是函数对象,所以它的Function.prototype值为函数原型对象
console.log(Function.prototype==Person.proto) //true

Array函数构造器new出来的是数组对象,所有其Array.prototype值为数组原型对象
console.log(Array.prototype==[].proto) //true

Object函数构造器new出来的是简单对象,所有其Object.prototype值为简单原型对象
console.log(Object.prototype=={}.proto) //true

你可能感兴趣的:(JavaScript的原型链的理解)