foreword
There is a concept that needs to be clear, only the constructor has the .prototype object, the object does not have this attribute, __proto__ is just a non-standardized way of accessing the prototype object of the constructor of the object provided by the browser;
prototype (prototype object)
A function is an object. Each function has a prototype attribute, and this attribute is the prototype object of the function. The attributes or methods defined on the prototype object will be inherited by the instance object of the function, and the instance object can directly access the prototype. A property or method in an object.
The prototype object is equivalent to a template for creating an instance, which stores various properties and methods of the instance;
For example: Array.prototype stores all the methods about arrays;
console.log(Array.prototype); // filter,find,map,push,pop,some,sort...
The object has no prototype (I feel that this sentence is a bit problematic), as follows:
console.log("123".prototype); // undefined
console.log({
name:'Eula'}.prototype); // undefined
console.log((123).prototype); // undefined
console.log([123].prototype); // undefined
_proto_ (connection of the prototype chain )
I don’t know if you have discovered the attribute __proto__ when debugging in the console. This attribute is actually an attribute automatically added to the instance by the JS engine when the instance is created. It is absolutely equal to the prototype attribute of its constructor
; That is to say, the __proto_ of the instance is the prototype object of this instance, but it is not recommended to directly access __proto__ in the code, __proto__ is also called the implicit prototype object.
as follows:
console.log("123".__proto__); // String类型
console.log({
name: "Eula" }.__proto__);// Object类型
console.log((123).__proto__); // Number类型
console.log([123].__proto__); // Arrary类型
It prints as follows:
In fact, it is equivalent to the following code: the order is one-to-one correspondence:
console.log(String.prototype);
console.log(Object.prototype);
console.log(Number.prototype);
console.log(Array.prototype);
说明
: Everything in js is an object, String, Object, Number, Array, etc. are built-in constructors of js. In js, because everything is an object, they can also be called built-in objects, and they have their own prototype objects. The topmost The prototype object of is Object
;
The methods used by their instantiated objects will search the respective prototype objects layer by layer until they are found;
其实这就是原型链的概念
:
When an instance wants to access a certain attribute, it first searches in the instance itself. If it is not found, it continues to search along the __proto__ object. If it finds that the final __proto__ object is null and does not find it, it returns an error that the attribute is not found. , and returns the property value if found. And this search path concatenated by several __proto__ objects is called the prototype chain.
Actual combat:
class Person {
constructor(name) {
this.name = name;
}
say() {
console.log(this.name + ":这个仇,我记下了。");
}
}
let Eula = new Person("优菈");
console.log("__proto__:", Eula.__proto__);
console.log("prototype:", Person.prototype);
console.log(Eula.__proto__ === Person.prototype);// true
The print is as follows:
We can find Eula.__proto__ === Person.prototype
that the instantiated object can access the prototype object through __proto__; since it can be accessed, we can also add our own properties and methods on it, as follows:
// 第一种添加方式
注意此处添加函数不能使用箭头函数 否则this将指向window
Eula.__proto__.fun = function() {
console.log('this:',this);
console.log("我的名字是:", this.name);
};
// 第二种添加方式
Person.prototype.age = 18;
Eula.fun();
console.log(Eula);
It prints as follows:
Use these two methods to add attributes and methods respectively. It should be noted that the method is added in the first method 不能使用箭头函数
, otherwise its pointing will point to window, so you will not be able to get the attributes under the Person class;
constructor
And you can also access the constructor through the prototype object :
console.log(Person);
console.log(Eula.__proto__.constructor === Person); //true
It prints as follows:
In fact, the above case is class
written by using, and function
the effect achieved by replacing it with the form is actually the same, as follows:
因为
: The essence of ES 6 class
is function. It can be regarded as a syntactic sugar, which makes the writing of object prototypes clearer and more like the syntax of object-oriented programming.
function Person(name) {
this.name = name;
this.say = function() {
console.log(this.name + ":这个仇,我记下了。");
};
}
let Eula = new Person("优菈");
Eula.__proto__.fun = function () {
console.log("this:", this);
console.log("我的名字是:", this.name);
};
Person.prototype.age = 18;;
console.log("__proto__:", Eula.__proto__);
console.log("prototype:", Person.prototype);
console.log(Eula.__proto__ === Person.prototype);// true
console.log(Eula.__proto__.constructor === Person); //true
Eula.fun();//新增的方法
Here is a flowchart about prototypes, constructors, instances, and prototype chains: it is not difficult to understand