javascript设计模式-面向对象

什么是面向对象(Object Oriented)

面向对象是一种程序设计思想。其中,对象是最小的程序单元,包含有属性(props)方法(methods)

类和实例

面向对象编程,其实目的就是为了降低代码耦合性。其中,有两个重要的概念: 类(class)实例(instance)

  • class: 是实例的抽象,是从实例中提取出公共的属性方法的集合。
  • instance: 是类的具象化,它拥有类的所有公共属性和方法。

简单的例子

/**
 * 定义Parent类
 */
class Parent {
  constructor (name, age) {
    this.name = name // 定义 name 属性
    this.age = age // 定义 age 属性
  }
  say () { // 定义 say 方法
    console.log(`${this.name}'s age is ${this.age}`)
  }
}

let p1 = new Parent('p1', 2)
p1.say() // p1's age is 2

let p2 = new Parent('p2', 18)
p2.say() // p2's age is 18

示例中,定义了一个Parent类,以及两个p1p2实例。其中,p1p2都有同一个say方法

可以看出,Parentp1p2两个的公共属性(name,age)以及公共方法(say)提取出来,这就是类是实例的抽象。

继承

当定义的基类无法满足我们的业务需求之后,那么就需要根据基类扩展相应的子类。

/**
 * 定义Animal类
 */
class Animal {
  constructor (name, age) {
    this.name = name // 定义 name 属性
    this.age = age // 定义 age 属性
  }
  say () { // 定义 say 方法
    console.log(`${this.name}'s age is ${this.age}`)
  }
}

/**
 * 定义People类,继承自Animal类
 */
class People extends Animal {
  constructor (name, age, where) {
    super(name, age)
    this.where = where
  }
  sleep () {
    console.log(`${this.name} sleep in ${this.where}`)
  }
}

/**
 * 定义Monkey类,继承自Animal类
 */
class Monkey extends Animal {
  constructor (name, age, food) {
    super(name, age)
    this.food = food
  }
  eat () {
    console.log(`${this.name} love ${this.food}`)
  }
}

let p1 = new People('p1', 10, 'male')
p1.sleep() // p1 sleep in male

let m1 = new Monkey('mk', 4, 'banana')
m1.eat() // mk love banana

封装


/**
 * 定义Parent类
 */
const getters = function (key) {
  return this._data[key]
}

const setters = function (key, val) {
  this._data[key] = val
}

class Parent {
  constructor () {
    this._data = {} // 定义一个伪私有变量
  }
  set (key, val) {
    setters.call(this, key, val)
  }
  get (key) {
    if (key === '_data') {
      return undefined // 阻止外部访问私有变量
    }
    return getters.call(this, key)
  }
}

let p1 = new Parent()
p1.set('name', 'p1')
console.log('name', p1.get('name')) // name p1
console.log('name', p1.get('_data')) // name undefined
console.log('name', p1._data) // name {name: "p1"} 

我们这种设计私有变量有一个缺陷,细心的童鞋应该能够察觉到。我们只能过滤通过get方式获取_data,但是无法过滤直接通过实例去调用_data这种途径。

我们可以使用ES6中的Proxy实现上面的缺陷,具体可以参考Vue2.0的设计源码。

ES6中 class私有属性和私有方法

多态

多态在Java中的应用就是面向接口编程。在Java中含有Interface接口的概念,这是在Javascaript中是没有相关概念的。

多态背后的思想是将“做什么”和“谁去做以及怎样去做”分离开来。。因为javascript是弱类型语言,这样传入参数无需进行类型判断,实现多态就会方便许多。

/**
 * say实现多态
 * @param {*} ins 传入的任意类型,无需类型判断
 */
const say = function (ins) {
  ins.speak()
}
class Dog {
  speak () {
    console.log('wowowow')
  }
}
class Duck {
  speak () {
    console.log('gagaga')
  }
}

say(new Dog())
say(new Duck())

javascript设计模式与开发实践(一)- 多态

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值