JavaScript 原型链

黄良钵

分类: 程序开发 623 1

是否能将对象作为原型?

是否能将对象作为原型?

使用Baby初始化child

使用Baby初始化child

apply和call方法

apply和call方法

Child原型链的形成

Child原型链的形成

代码和解释部分

HTML:

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

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. Student.prototype.constructor =
  9. Student.prototype.study = function(course,hours){
  10.     console.log(this.name +'学习' + course + hours + '个小时')
  11. }

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. Worker.prototype.work = function(task,hours){
  7.     console.log(this.name +task + hours + '个小时')
  8. }
  9. // 完全重写了原型链中的一个方法
  10. // Worker.prototype.play = function(game,hours){
  11. //     console.log(this.name + '找一个有山有水的地方')
  12. //     console.log(this.name + '玩' + game + hours + '个小时')
  13. // }
  14. Worker.prototype.play = function(game,hours){
  15.     console.log(this.name + '找一个有山有水的地方')
  16.     // 可以调用原型链中的任意一个方法
  17.     Child.prototype.play.call(this,game,hours)
  18.     console.log('假装去玩了')
  19. }
  • 0人 Love
  • 0人 Haha
  • 0人 Wow
  • 0人 Sad
  • 0人 Angry
JavaScript、原型链

作者简介: 黄良钵

打赏

博客站长,前端开发工程师

共 1 条评论关于 “JavaScript 原型链”

Loading...