虽然ES6虽然引入了class
关键字,但是,JavaScript关于类的概念任然是基于原型。
JavaScript关于属性和方法的复用和继承,都是通过对象,通过实例对象实现对构造函数的属性和方法的复用。
1. 构造函数
-
函数是JavaScript的一等公民,构造函数与普通函数并没有什么区别,只有当函数通过
new
关键字调用时,才称之为构造函数; -
通常将构造函数的首字母大写,以显示与普通函数的区别;
-
new
关键字调用便创建了实例对象;function Person() {} const person = new Person()
-
Person就是一个构造函数
-
person就是构造函数Person创建的实例对象
2. 原型对象
-
JavaScript的构造函数实例化一个对象的同时,具有一个属性:
prototype
, 称之为构造函数的原型对象。function Person() {}; const person = new Person(); console.log(Person.prototype);
2.1 prototype具有两个属性
- constructor属性
constructor属性指向了构造函数自身;
console.log(Person.prototype.constructor === Peron); //true
__proto__
属性
-
原型对象的
__proto__
属性并不是像它的实例对象person的__proto__
属性,实例对象的__proto__
属性指向其构造函数的原型对象,而原型对象的__proto__
属性,指向的是Object的对象原型,而非Person构造函数Function的原型对象;function Person() {}; const person = new Person() //Person的构造函数Function console.log(Person.constructor === Function); //true console.log(Person.__proto__ === Function.prototype); //true console.log(Person.prototype.__proto__ === Object.prototype); //true
-
由于prototype采用递归算法,该原型对象也有一个自己的属性(
__proto__
) ,
原型对象正是利用了递归算法和__proto__
属性,实现了对象属性和方法的继承;
function Person() {}
const person = new Person()
Object.prototype.msg = "落霞与孤鹜齐飞 秋水共长天一色";
console.log(person.msg);
3. 原型链
- JavaScript 对象有一个指向原型对象的链,当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该原型对象,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾;
function Person() {};
const person = new Person();
console.log(Person.prototype.__proto__ === Object.prototype); //true
console.log(Object.prototype.__proto__); //null
-
person访问属性时,首先在自身查找,如果查找不到就会通过
person.__proto__
到对象原型Proson.prototype上找, -
如果找不到,就会通过
Person.prototype.__proto__
向上一级原型对象查找, -
最后查找Object.prototype对象原型查找;
-
当
Object.prototype.__proto__
返回null时,结束查找; -
通过
__proto_
向上查找属性的链称之为原型链。
-
可以看出构造函数Object、Person并没有太多的分别,它们同为Function的实例对象;
-
JavaScript设计时并不是将原型链末端交给原型对象(Function.prototype),而是由Object原型对象(Object.prototype)承担;
function Person() {};
const person = new Person();
console.log(Person.prototype.__proto__ === Object.prototype); //true
console.log(Object.prototype.__proto__); //null
console.log(Object.constructor === Function); //true
console.log(Object.prototype.__proto__ === Function.__prototype); //false
console.log(Person.constructor === Function); //true
console.log(Person.prototype.__proto__ === Function.__prototype); //false
- 我们不妨看看Function身后有什么?
console.log(Function.constructor === Function); //true
console.log(Function.prototype.constructor === Function); //true
总结
这就是原型对象的终极“
- 实例对象通过
__proto__
关联上其构造函数的对象原型,进而通过对象原型的__proto__
与上一级构造函数之的原型对象的__proto__
关联,直至Object.prorotype.__proto__
=null为止,结束属性查找。 - 原型链就是通过这条关联关系实现了对象属性的继承。
参考文档
联系方式
联系方式
Email:yuanmin8888@outlook.com
微信: