js——构造函数 面向对象 继承

构造函数约定( 首字母大写 )

new 的作用过程:
创建一个新对象
将构造函数的作用域赋给新对象(因此 this 指向这个新对象)
执行构造函数中的代码(为这个新对象添加属性)
返回新对象

1、(注:此方法渐渐淘汰了)
//创建构造函数
function Person () {
  var obj = new Object()
  //属性
  obj.name = null
  obj.age = null
  obj.sex = null
  //方法
  obj.play = function () {
    console.log(this.name + '在玩')
  }
  obj.sleep = function () {
    console.log(this.name + '在睡觉')
  }
  //返回
  return obj
}

//调用构造函数
var p = Person()
p.name = 'lucy'
p.age = '18'
p.sex = 'girl'
console.log(p) // {name: "lucy", age: "18", sex: "girl", play: ƒ, sleep: ƒ}
p.play() // lucy在玩
2、(相比较1,可以清楚看出构造的是什么函数,且更加简易)

函数中的 this:
this 所在的函数在哪个对象中,this就代表这个对象
谁调用 this 就指代谁(例如:p.sayhi() 中若调用 this,则指代 p)
构造函数中 this,始终是 new 的当前对象

//创建构造函数
function Dog (json) {
  //属性
  this.name = json.name
  this.age = json.age
  this.dogFriends = json.dogFriends
  //方法
  this.eat = function (something) {
    console.log(this.name + '在吃' + something)
  }
}

//调用构造函数
var smallDog = new Dog({ name: 'lucy', age: '18', dogFriends: 'dd,xx' })
smallDog.age = 5 // 改值
console.log(smallDog) // Dog {name: "lucy", age: 5, dogFriends: "dd,xx", eat: ƒ}
smallDog.eat('奶') // lucy在吃奶
3、(推荐)
//创建构造函数
function Dog (json) {
  this._init(json)
}

Dog.prototype = {
  _init: function (json) {
    this.name = json.name
    this.age = json.name
    this.dogFriends = json.dogFriends
  },
  eat: function (something) {
    console.log(this.name + '在吃' + something)
  },
}

//调用构造函数
var smallDog = new Dog({ name: 'lucy', age: '18', dogFriends: 'dd,xx' })
smallDog.age = 5 // 改值
console.log(smallDog) // Dog {name: "lucy", age: 5, dogFriends: "dd,xx", eat: ƒ}
smallDog.eat('奶') // lucy在吃奶
  
// 创建静态方法
Dog.staticFun = function () {
  console.log('我是静态方法')
}
Dog.staticFun()

面向对象

function Fun() { }
Fun.prototype.get = function () { }
let fun = new Fun()

/* 以下都为 true */
console.log(fun.constructor.prototype === fun.__proto__);
console.log(fun.constructor.prototype.get === Fun.prototype.get);
console.log(fun.get === Fun.prototype.get);
console.log(fun.constructor === Fun);

这里写图片描述

var Dog = function () {
  return new Dog.prototype.init()
}
Dog.prototype = { //定义原型属性和方法
  constructor: Dog, //指向Dog函数
  //属性
  init: function () {
    this.name = 'lucy'
    this.age = '18'
  },
  //方法
  about: function () {
    console.log(this.name + '今年已经' + this.age + '了')
  },
}
Dog.prototype.init.prototype = Dog.prototype // 右边黑色转换为红色指向线

var dog = new Dog()
dog.name = 'bob' // 定义实例方法(bob代替了lucy)
dog.about() // bob今年已经18了

访问时,若是实例中有属性,则直接使用实例,否则找它的原型

继承

创建构造函数

function BigDog (json) {
  this.name = json.name
  this.age = json.age

  this.eat = function (something) {
    console.log(`${this.age} 岁大的 ${this.name} 在吃 ${something}`)
  }
}

BigDog.prototype.play = function (something) {
  console.log(`${this.name} 在玩 ${something}`)
}

继承 BigDog 的方法

对象冒充

function SmallDog1 (json) {
  BigDog.call(this, json) // 对象冒充继承
}

// 在实例化子类时可以给父类传参
let dog1 = new SmallDog1({ name: 'lucy', age: 10 })

// 问题:对象冒充可以继承构造函数里面的属性和方法,但无法继承原型链的
// dog.play('ball') // 报错
dog1.eat('零食')

原型链

function SmallDog2 () {}

SmallDog2.prototype = new BigDog({ name: 'bob', age: 20 })
// 问题:在实例化子类时无法给父类传参
let dog2 = new SmallDog2()
// 原型链实现继承:可以继承构造函数里面的属性和方法,也可以继承原型链上面的属性和方法
dog2.play('ball')
dog2.eat('foods')

原型链 + 对象冒充

function SmallDog3 (obj) {
  BigDog.call(this, obj)
}

// SmallDog3.prototype = new BigDog()
// 推荐选用这种原型链继承,避免重复继承构造函数里面的属性和方法从而浪费性能
SmallDog3.prototype = BigDog.prototype

let dog3 = new SmallDog3({ name: 'tom', age: 66 })
dog3.play('game')
dog3.eat('banana')

补充

  • 原型链上面的属性会被多个实例共享,构造函数不会
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值