This article has participated in the "Newcomer Creation Ceremony" event to start the road of gold creation together.
foreword
Prototype chain has always been a common question in js interviews, and it is also a very core basic knowledge of js. Maybe it will not be used often, but understanding it will greatly deepen your understanding of the language. This article introduces the prototype chain in a very easy-to-understand way. , read it patiently, I believe it will be able to help you.
Constructors and Instances
Suppose you declare a method called Foo()
, then we can declare the instance with new Foo().
function Foo() {
console.log("我是一个构造方法");
}
const f1 = new Foo();
复制代码
Now you can clearly understand that Foo() is 构造函数
and f1 is its 实例
.
Property Prototype
The Foo() constructor is a method.
A method is also an object data type, so it can be said that a method is an object.
Objects have attributes, but they 方法
have their own special attribute, called prototype
, other objects don't.
This property will point to one 原型对象(Foo.prototype)
, and the prototype object will also have its own property called constructor
, and the pointing property contains a pointer that points back to the original constructor.
function Foo() {
console.log("我是一个构造方法");
}
const f1 = new Foo();
console.log(Foo.prototype);//Foo的原型对象
console.log(f1.prototype);//f1没有 underfied
复制代码
property __proto__
The above prototype is to 构造函数的所有实例
provide shared methods and properties.
How do instances access shared methods and properties?
The f1 instance does not have a prototype, but has an attribute __proto__, which is an attribute that all objects have, and it points to 构造自己的构造函数
, 原型对象
and then the js language allows the instance to access shared attributes and methods based on this attribute.
Foo is the constructor of f1, Foo.prototype is the prototype object of Foo, so f1.__proto__ points to Foo.prototype
function Foo() {
console.log("我是一个构造方法");
}
const f1 = new Foo();
console.log(Foo.prototype);
console.log(f1.__proto__);
复制代码
access methods on the prototype
If the constructor of Foo wants its own instance to have the same property, such as name, add it to its own prototype object.
function Foo() {
console.log("我是一个方法");
}
Foo.prototype.name = "我是Foo创造的实例共享的属性";
const f1 = new Foo();
const f2 = new Foo();
console.log(f1.name);//我是Foo创造的实例共享的属性
console.log(f2.name);//我是Foo创造的实例共享的属性
复制代码
Brief summary of the above
sequenceDiagram
实例f1 ->> 构造函数Foo: 通过new的形式创造
构造函数Foo->>构造函数的原型对象Foo.prototype: prototype
构造函数的原型对象Foo.prototype->>构造函数Foo: constructor
实例f1->>构造函数的原型对象Foo.prototype: __proto__
Constructors also have __proto__
It is said that all objects have __proto__, and Foo is a function and an object, so what is Foo.__proto__?
那就去找Foo的构造函数是谁呢,Foo是一个函数,拥有函数特有的方法和属性,创造的它的构造函数就是Function,这个js自带的的一个构造函数,它的Function.prototype给所有js中你创建的函数提供函数自带的一些公共方法和属性。
所以Foo.__proto__指向Funtion.prototype
构造函数的原型也有__proto__
Foo.prototype也是对象,所以它也有__proto__。
每当我们要找__proto__,就得找它的构造函数,Foo.prototype是个对象,纯对象,所以它的构造函数是Object,那么Object的原型就是Object.prototype。
Foo.prototype.__proto__指向Object.prototype
Object.prototype这个原型对象很特殊
Array、String、Funtion、Object
这些构造函数
都是函数
,都是Funtion
构造函数的实例。 Array.__proto__、String.__proto__、Funtion.__proto__、Object.__proto__
指向Funtion.prototype
原型, 可以调用Funtion.prototype
原型的一些公共方法, 例如都可以调用.name查看自己的函数名字。
Array.prototype、String.prototype、Funtion.prototype
这些原型对象
都是对象
,都是Object
构造函数的实例。 Array.prototype.__proto__、String.prototype.__proto__、Funtion.prototype.__proto__
指向Object.prototype
原型, 所以可以调用Object.prototype
这个原型对象的公共方法,
而Object.prototype
有些特殊,它虽然是对象,但是并不是Object自己的实例, Object.prototype.__proto__指向null
,作为原型链的终点
总结
- 方法,也就是函数,才有
prototype
,就是方法的原型。 - 所以实例,一般都会有个对应的构造方法,也就是构造函数,实例的
__proto__
指向构造方法的原型。 - js有很多自带的构造方法,例如Array、String、Funtion、Object,都是根据js一些对象类型分配的,他们的原型上提供了许多封装好的常用方法。
- 所有
构造方法
本身是函数
,是Funtion
这个js自带构造函数的实例
。 - 除了Object.prototype,所有
构造方法的原型
本身是对象
,是Object
这个js自带构造函数的实例
。 - Object.prototype.__prototype指向
null
,作为原型链重点
。
尾言
如果哪里让你有什么意见建议,请提出,我会即使反馈的,谢谢。