原型链是JS基础知识之一,翻阅那么多的文章,不如自行总结一下,温故而知新。
关于原型链,绕不开几个关键词,prototype,proto,constructor,new等,这里总结下。
如有错误,欢迎斧正。
prototype
是函数身上的属性,__proto__
是对象身上的属性,constructor
是对象身上的属性
实例化对象的__proto__
指向的是创建该实例的原型对象,实例原型的constructor
会是构造函数,实例原型的__proto__
指向的是上一级,如果没有其它的对象原型,那就会是Object的实例原型。
关于这点,可以参考下面这张图,摘自网上。
- constructor这个构造函数,存在于两个地方,一个是es6类写法下的构造函数,一个就是如上对象的构造函数属性。es6 class本身就只是个语法糖,底层原理还是原型链,因此都是一个意思,即构造函数即创建该实例的函数。
- 原型链指的是继承链条上的各个对象,而不是函数。
原型链的好处
区分于类继承方式的一种继承,比较灵活,比如B.prototype=new A(),当我们创建B的实例即可拥有A的方法。
测试题
收集以下几道题来测试下理解。
题1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| function Fn(){ var a = 12 this.getName = function(){ console.log('private getName') } }
Fn.prototype.getName = function (){ console.log('public getName') }
var fn = new Fn() var fn1 = new Fn()
console.log(fn.a) console.log(fn.getName())
console.log(fn.getName === fn1.getName) console.log(fn.__proto__.getName === fn1.__proto__.getName) console.log(fn.__proto__.getName === Fn.prototype.getName)
console.log(fn.hasOwnProperty ===Object.prototype.hasOwnProperty) console.log(fn.constructor === Fn)
|
题2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| function P() {} var p1 = new P(); P.prototype.age = 18; P.prototype = { constructor: P, name: 'zz' }; P.prototype.num = 20; P.prototype.age = 20; console.log(p1.name); console.log(p1.age, 'dd'); console.log(p1.num); var p2 = new P(); console.log(p2.name);
|
题3
1 2 3 4 5 6
| function test() {} console.log(test.prototype.constructor.constructor);
|
写在最后
理解这些基本的概念,才是写好代码的基础。
参考资料