一个示例捋顺JS原型链

如果还不是很清楚JS原型链的小伙伴,可以把下面的代码运行一下,细细品味~

 1 // 1.构造函数
 2 function Dog(name){
 3   this.name = name
 4   this.action = function(msg){
 5     console.info(msg)
 6   }
 7 }
 8 
 9 // 2.使用构造函数Dog创建的实例对象
10 var xiaohua = new Dog('小花')
11 // 实例对象xiaohua可以使用构造函数中的属性、方法
12 console.info(xiaohua.name) // 小花
13 var xiaohei = new Dog('小黑')
14 xiaohei.action('摇尾巴') // 摇尾巴
15 
16 // 3.直接使用构造函数中的方法,每个实例对象中方法都会复制一份,造成内存浪费
17 // 如下两个实例对象相同的方法不相等
18 console.info(xiaohua.action === xiaohei.action) // false
19 
20 // 4.使用原型
21 // 每一个构造函数均有一个prototype属性,该属性是一个对象,其所有方法和属性都被构造函数所拥有,
22 // 因此,可以把不变的属性和方法定义在prototype对象上,所有的实例都可以共享这些属性和方法
23 
24 // 给构造函数Dog的原型添加属性和方法
25 Dog.prototype.favourite = '骨头'
26 Dog.prototype.barking = function (){
27   console.info('汪汪汪...')
28 }
29 // 实例中可以直接使用
30 console.info(xiaohua.favourite) // 骨头
31 // 而且原型中的方法是共享的
32 console.info(xiaohua.barking === xiaohei.barking) // true
33 
34 // 5.构造函数的原型对象和实例的关系
35 // 每个实例对象都有一个__proto__属性(原型),指向构造函数的原型对象prototype,所以实例对象可以使用构造函数原型中的方法
36 console.info(xiaohua.__proto__ === Dog.prototype) // true
37 
38 // 实例对象可以使用方法:1.自身拥有的方法,2.顺着__proto__找到的构造函数prototype的方法
39 
40 
41 // 6.原型对象prototype和构造函数的关系
42 // 原型对象prototype有constructor属性,该属性为构造函数本身
43 console.info(Dog.prototype.constructor === Dog) // true
44 // 有因为实例对象的__proto__等于构造函数的prototype,所以每个实例的__proto__.constructor即是构造函数
45 console.info(xiaohua.__proto__.constructor === Dog) // true
46 console.info(xiaohei.__proto__.constructor === Dog) // true
47 
48 // 通过实例的__proto__.constructor属性可以明确是由哪个构造函数创建出来的
49 
50 //7.特殊情况需要手动把constructor属性指回来
51 // 如重新给prototype赋值,会造成constructor丢失
52 Dog.prototype = {
53   barking: function (){
54     console.info('汪汪汪...')
55   }
56 }
57 // 因为重新给Dog.prototype赋值了一个对象
58 console.info(Dog.prototype.constructor === Dog) // false
59 
60 // 手动把constructor属性指回来
61 Dog.prototype = {
62   constructor: Dog,
63   barking: function (){
64     console.info('汪汪汪...')
65   }
66 }
67 console.info(Dog.prototype.constructor === Dog) // true
68 
69 // 8.原型对象(prototype)的原型(__proto__)
70 // 原型对象也是对象,因此也因该有原型,即Dog.prototype.__proto__
71 // 而这个原型对象的原型(Dog.prototype.__proto__)是Object构造函数的原型对象
72 console.info(Dog.prototype.__proto__ === Object.prototype) // true
73 // 也即是这个原型对象的原型的constructor属性(Dog.prototype.__proto__.constructor)为Object
74 console.info(Dog.prototype.__proto__.constructor === Object) // true
75 //这个原型对象的原型 的原型是null
76 console.info(Dog.prototype.__proto__.__proto__)  // null
77 
78 // 以上即是原型链

最后附上pink老师画的原型链示意图:

 

猜你喜欢

转载自www.cnblogs.com/jyughynj/p/12547263.html