继承与组合

179 阅读2分钟

为什么有类
不同的对象属性重复了,就有了类
为什么有继承
不同类的属性重复了就有了继承
对象的属性重复了

继承

类:可声明对象的自身属性和函数,共有属性和共有方法。
功能单一,功能没有太多交叉的地方,一眼能看出继承关系,前端库喜欢用继承

let person1 = {
	name:'frank',age:18,sayHi(){}
}
let person2 = {
	name:'jack',age:23,sayHi(){}
}
class Person{//ts写法
	sayHi():void{}
    constructor(public name:string,public age:number ){
    }
}
//小细节
class App extends React.Component {
  name = '狗子'
  // log() {//写在原型上
  //   console.log(`请叫我${this.name}`)
  // }
  log = () => {//写在实例上
    console.log(`请叫我${this.name}`)
  }
  render() {//子类重写了父类的所有属性,多态的意思是不同的子类对同一个消息有不同的反应
    //这里重写了render
    console.log('xxx')
    return (
      <div className="App" >
        <button onClick={this.log}>
          打招呼
        </button>
      </div>
    )
  }
}

继承的缺点

//不够灵活,当继承时会继承父类的全部属性方法,而我们往往只需要其中某一个,当我们依赖多个功能时继承多层,就会变得臃肿,对于结构比较清晰的业务以及基础组件库这种(垂直性业务)我们使用继承会很容易理清楚层级关系
class App {
  name = '狗子'
  add() { }
  count() { }
  render() { }
  on() { }
  emit() { }
  off() { }
}
function doSomething() {
  return xxx
  console.log('做点什么')
}
class App2 extends App {
  //此时拥有父类所有功能
  //但此时我想用一个写好的方法doSomething ,就只能有两个选择,要么直接写到App2,要么把doSomething写到一个类里去继承它,多层继承适用于垂直性,不适合交叉性业务
  spend() { }
}

组合

//这是react中的一个自定义hooks,这就是一种组合形式,暴露出对应的接口,需要用什么就引什么
但组合的缺点也是太灵活

import {useState,useEffect} from 'react'
import createId from 'helpers/createId'
import {useUpdate} from 'hooks/useUpdate'

const useTags = ()=>{
    const [tags,setTags] = useState([])
    useEffect(()=>{//第一次进来执行
        setTags(JSON.parse(window.localStorage.getItem('tags')||'[]'))
    },[])
    useUpdate(()=>{
        window.localStorage.setItem('tags',JSON.stringify(tags))
    },tags)

    const findTag = (id) =>{
        return tags.filter(item=>item.id === id)[0]
    }
    const updateTag = (id,name) =>{
        setTags(tags.map(item=>item.id===id?{id,name}:item))
    } 
    const deleteTag = (id) =>{
        setTags(tags.filter(item=>item.id!==id))
    }
    const addTag = ()=>{
        const name = window.prompt('请输入标签名')
        if(name!== null){
            if(name.length > 0){
                if(tags.map(item=>item.name).indexOf(name)>=0){
                    alert('标签名重复')
                }else{
                    setTags(state=>[...state,{id:createId(),name}])
                }
            }else{
                window.alert('内容不能为空哒')
            }
        }
    }
    return {tags,setTags,findTag,updateTag,deleteTag,addTag}
}