是否能将对象作为原型?

使用Baby初始化child

apply和call方法

Child原型链的形成

代码和解释部分
**HTML:**
1. <!DOCTYPE html>
2. <html>
3.
4. <head>
5. <meta charset="utf-8">
6. <title>原型链</title>
7. <script src="Baby.js"></script>
8. <script src="child.js"></script>
9. <script src="Student.js"></script>
10. <script src="work.js"></script>
11. <style>
12.
13. </style>
14. </head>
15.
16. <body>
17. <script>
18. var baby = new Baby('wangzihao', true, new Date(2014, 5, 1, 12, 0, 0))
19. console.log(baby)
20. baby.eat('苹果')
21. console.log(baby.getAge())
22. baby.sleep(12)
23. baby.name = '123456'
24. baby.age = 13
25.
26.
27. console.log(baby)
28. var child = new Child('liquanfu', true, new Date(2013, 5, 1, 12, 3, 3))
29. // child.eat('ff')
30. console.log(child)
31. child.play('堆积木', 8)
32.
33. var student = new Student('小王', true, new Date(2013, 5, 1, 12, 3, 3))
34. console.log(student)
35. student.eat('螃蟹')
36. student.play('lol', 12)
37. student.study('HTML', 24)
38.
39. var worker = new Worker('王军', true, new Date(2013, 5, 1, 12, 3, 3))
40. worker.eat('手抓饼')
41.
42. worker.study('lol', 24)
43. worker.work('写代码', 38)
44. worker.play('lol', 24)
45.
46. console.log('-'.repeat(30))
47.
48. console.log(worker instanceof Worker)
49. // worker对象 是Worker构造函数的一个实例
50. console.log(worker instanceof Student)
51. console.log(worker instanceof Child)
52. console.log(worker instanceof Baby)
53. console.log(worker instanceof Object)
54. // worker对象也是Student Child Baby Object构造函数的实例
55.
56. console.log(student instanceof Worker)
57. console.log(student instanceof Student)
58. // student 对象不是Worker构造函数的实例
59.
60. // 一个worker对象能否当成一个student对象来使用呢?
61. // 一个worker对象能否当成一个child对象来使用呢?
62. // 在语法上完全可以把worker对象当成student或者child来使用
63. // 因为worker具有student和child所具有的所有属性和方法
64. // 在语义上可能会有所不同 比如worker的play方法与child的play方法是不一样的
65.
66. console.log(typeof worker)
67. console.log(typeof student)
68.
69. // 如果你想得到一个构造函数怎么办?
70. console.log(worker.constructor)
71. // 得到一个构造函数 并不是构造函数的名字
72.
73. // console.log(worker.constructor.name)
74. var code = worker.constructor.toString()
75. console.log(code)
76. var index = code.indexOf('(')
77. console.log(index)
78. var name = code.substring(9,index)
79. console.log(name)
80.
81. var worker1 = Object.getPrototypeOf(worker)
82. var worker2 = Object.getPrototypeOf(worker1)
83. var worker3 = Object.getPrototypeOf(worker2)
84. console.log(worker3)
85. // Object.getPrototypeOf() 可以获取指定对象的原型
86.
87. console.log(worker3.isPrototypeOf(worker))
88. // 判断一个对象是否在指定对象的原型链中
89. console.log(child.isPrototypeOf(worker)) //false
90. // 在搭建worker构造函数的原型链时根本没有使用child对象
91. // 而是使用child构造函数的原型
92.
93. </script>
94. </body>
95.
96. </html>
**Baby.js**
1. function Baby(name,isMale,birthDate){
2. this.name = name
3. this.isMale = isMale
4. this.birthDate = birthDate
5. Object.freeze(this)
6. }
7. Baby.prototype.eat = function(food){
8. console.log(this.name + '喜欢吃' + food)
9. }
10. Baby.prototype.sleep = function(hours){
11. console.log(this.name + '睡了' + hours +'个小时')
12. }
13. Baby.prototype.getAge = function(){
14. return new Date().getFullYear() - this.birthDate.getFullYear()
15. }
**child.js**
1. function Child(name,isMale,birthDate){
2. // this.name = name
3. // this.isMale = isMale
4. // this.birthDate = birthDate
5. // 能不能调用Baby的构造函数
6. // Baby(name,isMale,birthDate)
7. // 没有this指针 当前对象不会收到name isMale等值 而且会报错
8.
9. // Baby.call(this,name,isMale,birthDate)
10. Baby.apply(this,[name,isMale,birthDate])
11. // 第一个参数决定被调用函数Baby内部的this
12. // 其它参数是被调用函数的参数
13. }
14. // Child.prototype = new Baby()
15. // 我们只是想使用baby对象中的方法 并不是真的需要一个baby对象
16. // 而且new Baby()需要传递参数 但我们并没有参数可传
17. // Child.prototype = Baby.prototype
18. // 会导致Baby的原型和Child的原型成为同一个原型
19. // 那么当下面为child的原型添加新方法的时候 新方法也会出现在Baby中
20.
21. // 空的构造函数
22. function TemConstructor(){}
23. TemConstructor.prototype = Baby.prototype
24. var tempObject = new TemConstructor()
25. // 创建一个空白对象 这个空白对象里面什么东西都没 但它的原型和Baby原型是同一个原型
26. Child.prototype = tempObject
27. // Child的原型等于刚创建的空白对象
28.
29. Child.prototype.constructor = Child
30. // 为Child的原型添加一个constructor 指定Child的构造函数
31. // 添加之后可以方便的通过对象获取它的构造函数
32.
33. // 创建一个原型链 原型链:对象的原型是一个对象 这个对象也有原型
34. // 这个原型也是一个对象 这个对象也是原型 这个原型也是对象.......
35. // 就构成了原型链 直到对象的原型为null为止
36.
37. // 当在一个对象上调用方法及属性时 会沿着原型链一直找 直到找到一个或是
38. // 最终找完整个原型链仍然没有找到为止
39. Child.prototype.play = function(game,hours){
40. console.log(this.name + '玩' + game + hours + '小时' )
41. }
**Student.js**
1. function Student(name,isMale,birthDate){
2. // 通过call方法 你可以在一个对象上调用另一个对象上的方法
3. Child.call(this,name,isMale,birthDate)
4. }
5. Student.prototype = Object.create(Child.prototype)
6. // Object.create()可以通过你提供的原型创建一个新对象
7. // 这个对象的新原型就是create()的第一个参数
8.
9. Student.prototype.constructor =
10.
11. Student.prototype.study = function(course,hours){
12. console.log(this.name +'学习' + course + hours + '个小时')
13. }
**work.js**
1. function Worker(name,isMale,BirthDate){
2. Student.call(this,name,isMale,BirthDate)
3. }
4. Worker.prototype = Object.create(Student.prototype)
5. Worker.prototype.constructor = Worker
6.
7. Worker.prototype.work = function(task,hours){
8. console.log(this.name +task + hours + '个小时')
9. }
10. // 完全重写了原型链中的一个方法
11. // Worker.prototype.play = function(game,hours){
12. // console.log(this.name + '找一个有山有水的地方')
13. // console.log(this.name + '玩' + game + hours + '个小时')
14. // }
15.
16. Worker.prototype.play = function(game,hours){
17. console.log(this.name + '找一个有山有水的地方')
18. // 可以调用原型链中的任意一个方法
19. Child.prototype.play.call(this,game,hours)
20. console.log('假装去玩了')
21. }