是否能将对象作为原型?
使用Baby初始化child
apply和call方法
Child原型链的形成
代码和解释部分
HTML:
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- <title>原型链</title>
- <script src="Baby.js"></script>
- <script src="child.js"></script>
- <script src="Student.js"></script>
- <script src="work.js"></script>
- <style>
- </style>
- </head>
- <body>
- <script>
- var baby = new Baby('wangzihao', true, new Date(2014, 5, 1, 12, 0, 0))
- console.log(baby)
- baby.eat('苹果')
- console.log(baby.getAge())
- baby.sleep(12)
- baby.name = '123456'
- baby.age = 13
- console.log(baby)
- var child = new Child('liquanfu', true, new Date(2013, 5, 1, 12, 3, 3))
- // child.eat('ff')
- console.log(child)
- child.play('堆积木', 8)
- var student = new Student('小王', true, new Date(2013, 5, 1, 12, 3, 3))
- console.log(student)
- student.eat('螃蟹')
- student.play('lol', 12)
- student.study('HTML', 24)
- var worker = new Worker('王军', true, new Date(2013, 5, 1, 12, 3, 3))
- worker.eat('手抓饼')
- worker.study('lol', 24)
- worker.work('写代码', 38)
- worker.play('lol', 24)
- console.log('-'.repeat(30))
- console.log(worker instanceof Worker)
- // worker对象 是Worker构造函数的一个实例
- console.log(worker instanceof Student)
- console.log(worker instanceof Child)
- console.log(worker instanceof Baby)
- console.log(worker instanceof Object)
- // worker对象也是Student Child Baby Object构造函数的实例
- console.log(student instanceof Worker)
- console.log(student instanceof Student)
- // student 对象不是Worker构造函数的实例
- // 一个worker对象能否当成一个student对象来使用呢?
- // 一个worker对象能否当成一个child对象来使用呢?
- // 在语法上完全可以把worker对象当成student或者child来使用
- // 因为worker具有student和child所具有的所有属性和方法
- // 在语义上可能会有所不同 比如worker的play方法与child的play方法是不一样的
- console.log(typeof worker)
- console.log(typeof student)
- // 如果你想得到一个构造函数怎么办?
- console.log(worker.constructor)
- // 得到一个构造函数 并不是构造函数的名字
- // console.log(worker.constructor.name)
- var code = worker.constructor.toString()
- console.log(code)
- var index = code.indexOf('(')
- console.log(index)
- var name = code.substring(9,index)
- console.log(name)
- var worker1 = Object.getPrototypeOf(worker)
- var worker2 = Object.getPrototypeOf(worker1)
- var worker3 = Object.getPrototypeOf(worker2)
- console.log(worker3)
- // Object.getPrototypeOf() 可以获取指定对象的原型
- console.log(worker3.isPrototypeOf(worker))
- // 判断一个对象是否在指定对象的原型链中
- console.log(child.isPrototypeOf(worker)) //false
- // 在搭建worker构造函数的原型链时根本没有使用child对象
- // 而是使用child构造函数的原型
- </script>
- </body>
- </html>
Baby.js
- function Baby(name,isMale,birthDate){
- this.name = name
- this.isMale = isMale
- this.birthDate = birthDate
- Object.freeze(this)
- }
- Baby.prototype.eat = function(food){
- console.log(this.name + '喜欢吃' + food)
- }
- Baby.prototype.sleep = function(hours){
- console.log(this.name + '睡了' + hours +'个小时')
- }
- Baby.prototype.getAge = function(){
- return new Date().getFullYear() - this.birthDate.getFullYear()
- }
child.js
- function Child(name,isMale,birthDate){
- // this.name = name
- // this.isMale = isMale
- // this.birthDate = birthDate
- // 能不能调用Baby的构造函数
- // Baby(name,isMale,birthDate)
- // 没有this指针 当前对象不会收到name isMale等值 而且会报错
- // Baby.call(this,name,isMale,birthDate)
- Baby.apply(this,[name,isMale,birthDate])
- // 第一个参数决定被调用函数Baby内部的this
- // 其它参数是被调用函数的参数
- }
- // Child.prototype = new Baby()
- // 我们只是想使用baby对象中的方法 并不是真的需要一个baby对象
- // 而且new Baby()需要传递参数 但我们并没有参数可传
- // Child.prototype = Baby.prototype
- // 会导致Baby的原型和Child的原型成为同一个原型
- // 那么当下面为child的原型添加新方法的时候 新方法也会出现在Baby中
- // 空的构造函数
- function TemConstructor(){}
- TemConstructor.prototype = Baby.prototype
- var tempObject = new TemConstructor()
- // 创建一个空白对象 这个空白对象里面什么东西都没 但它的原型和Baby原型是同一个原型
- Child.prototype = tempObject
- // Child的原型等于刚创建的空白对象
- Child.prototype.constructor = Child
- // 为Child的原型添加一个constructor 指定Child的构造函数
- // 添加之后可以方便的通过对象获取它的构造函数
- // 创建一个原型链 原型链:对象的原型是一个对象 这个对象也有原型
- // 这个原型也是一个对象 这个对象也是原型 这个原型也是对象.......
- // 就构成了原型链 直到对象的原型为null为止
- // 当在一个对象上调用方法及属性时 会沿着原型链一直找 直到找到一个或是
- // 最终找完整个原型链仍然没有找到为止
- Child.prototype.play = function(game,hours){
- console.log(this.name + '玩' + game + hours + '小时' )
- }
Student.js
- function Student(name,isMale,birthDate){
- // 通过call方法 你可以在一个对象上调用另一个对象上的方法
- Child.call(this,name,isMale,birthDate)
- }
- Student.prototype = Object.create(Child.prototype)
- // Object.create()可以通过你提供的原型创建一个新对象
- // 这个对象的新原型就是create()的第一个参数
- Student.prototype.constructor =
- Student.prototype.study = function(course,hours){
- console.log(this.name +'学习' + course + hours + '个小时')
- }
work.js
- function Worker(name,isMale,BirthDate){
- Student.call(this,name,isMale,BirthDate)
- }
- Worker.prototype = Object.create(Student.prototype)
- Worker.prototype.constructor = Worker
- Worker.prototype.work = function(task,hours){
- console.log(this.name +task + hours + '个小时')
- }
- // 完全重写了原型链中的一个方法
- // Worker.prototype.play = function(game,hours){
- // console.log(this.name + '找一个有山有水的地方')
- // console.log(this.name + '玩' + game + hours + '个小时')
- // }
- Worker.prototype.play = function(game,hours){
- console.log(this.name + '找一个有山有水的地方')
- // 可以调用原型链中的任意一个方法
- Child.prototype.play.call(this,game,hours)
- console.log('假装去玩了')
- }
很赞的文章,图片处理不错,适合初学者