es6中的class类的总结

class类的学习

一、class类的简介

  1. 传统的JS只有对象的概念,没有class类的概念,因为JS是基于原型的面向对象语言
举个栗子:
// 构造函数
function Person(name) {
	this.name = name
}
Person.prototype.say = function() {
    return `My name is ${this.name}`
}

// 实例化
const p = new Person('zhangsan')
console.log(p.say())
  1. ES6引入class类的概念,通过关键字class来定义类
举个栗子:
class Person {
    // 构造函数 类被实例化就会立即调用
	constructor(name) {
        this.name = name // this表示的是实例化对象 即p
    }
    say() {
        return `My name is ${this.name}`
    }
}

// 类的实例化
const p = new Person('lisi')
console.log(p.say())

二、类的继承

  1. 使用关键字extends来继承父类
  2. 必须使用super()来将父类实例对象上的属性和方法加到子类的this上
  3. 如果子类没有constructor(),super()会自动加上
  4. 子类会继承父类的属性和方法
  5. 静态属性和静态方法必须通过类的类名来调用(关键字static)
举个栗子:
class Father {
    // 静态属性 可以被类调用
    static prop = 1

    constructor(surname, gender) {
        this.surname = surname
        this.gender = gender
    }
    say() {
        return `My surname is ${this.surname}`
    }
    sleep(){
        return 'Father will go to sleep'
    }
	// 静态方法 可以被类调用 (this指向的是类而不是类的实例)
    static work() {
        return 'I will go to work'
    }
}

class Son extends Father {
	constructor(surname, gender, skill) {
        super(surname, gender)
        this.skill = skill
    }
    // 重写父类的say()方法
    // say() {
    //     return '子类的say()方法'
    // }
    say() {
        super.say()  // 继承父类的say() 方法
        return '子类的say()方法'
    }
    study() {
        return `Son can ${this.skill.join('、')}`
    }
}

// 类的实例化
const p = new Son('wang', 'man', ['弹钢琴', '跳舞', '游泳'])
console.log(p.say())
console.log(p.sleep())
console.log(p.study())

console.log(Son.prop,'----------1')
console.log(Son.work(),'----------2')
console.log(Father.prop,'----------1')
console.log(Father.work(),'----------2')

console.log(p.prop,'----------3')     // undefined
// console.log(p.work(),'----------3')    // 报错

三、类的注意事项

  1. 在类中定义方法时候,不可以给方法加上function关键字,因为JS中构造函数是用function定义的,两个隔开。
    请添加图片描述

  2. 所有方法不要用逗号隔开,否则会报错。
    请添加图片描述

  3. 函数模拟是有变量提升功能的,因为默认函数就是提升的,但是class类是没有提升功能的
    请添加图片描述

请添加图片描述

四、class类应用

1. es6实现拖拽:

<script>
    /**
         * 功能:拖拽(鼠标按下、移动、放开)
         *      
         *      div1为父类,可基础拖拽;div2是子类,限制拖拽的位置(不可以拖拽出屏幕)
         *      constructor()构造器相当于初始化方法
         */
    class Drag {
        constructor(id) {
            this.oDiv = document.querySelector(id)
            this.divX = 0
            this.divY = 0

            this.oDiv.onmousedown = this.fnDowm.bind(this)
        }
        // 鼠标按下去时,获取div1距离左边和顶部的距离
        fnDowm(e) {
            this.divX = e.clientX - this.oDiv.offsetLeft
            this.divY = e.clientY - this.oDiv.offsetTop

            document.onmousemove = this.fnMove.bind(this)
            document.onmouseup = this.fnUp.bind(this)

            // 阻止默认事件 (可选中文字)
            e.preventDefault()
        }
        // 鼠标移动
        fnMove(e) {
            this.oDiv.style.left = e.clientX - this.divX + 'px'
            this.oDiv.style.top = e.clientY - this.divY + 'px'
        }
        // 鼠标放开
        fnUp(e) {
            document.onmousemove = null
            document.onmouseup = null
        }
    }

    // 子类继承
    class LimitDrga extends Drag {
        fnMove(e) {
            // 继承父类的移动方法
            super.fnMove(e)

            // 子类自己的方法:限制移动的位置
            this.oDiv.style.left = this.oDiv.offsetLeft <= 0 ? 0 : this.oDiv.offsetLeft
            this.oDiv.style.top = this.oDiv.offsetTop <= 0 ? 0 : this.oDiv.offsetTop
        }
    }

    // 调用
    new Drag('#div1')
    new LimitDrga('#div2')
</script>

2. react实现拖拽:

父类

export default class extends Component {
    constructor() {
        super()
        this.divX = 0
        this.divY = 0

        this.state = {
            needX: 0,
            neddY: 0
        }
    }

    fnDown = () => {
        return (e) => {
            this.divX = e.clientX - e.target.offsetLeft
            this.divY = e.clientY - e.target.offsetTop

            document.onmousemove = this.fnMove.bind(this)

            e.preventDefault()
        }
    }

    fnMove(e) {
        this.setState({
            needX: e.clientX - this.divX + 'px',
            needY: e.clientY - this.divY + 'px'
        })
    }

    fnUp = () => {
        return (e) => {
            document.onmousemove = null
        }
    }

    render() {
        return (
            <div className="box1" id="div1" style={{left: this.state.needX, top: this.state.needY}} onMouseDown={this.fnDown()} onMouseUp={this.fnUp()}>DIV1</div>
        )
    }
}

子类

export default class extends Drag {
    fnMove(e) {
        // 继承父类的move方法,但子类还可以在父类的方法上添加自己的逻辑
        super.fnMove.bind(this)
        
        this.state.needX = e.clientX - this.divX <= 0 ? 0 : e.clientX - this.divX + 'px'
        this.state.needY = e.clientY - this.divY <= 0 ? 0 : e.clientY - this.divY + 'px'
        this.setState({})
    }
    render() {
        return (
            <div className="box2" id="div2" style={{left: this.state.needX, top: this.state.needY}} onMouseDown={this.fnDown()} onMouseUp={this.fnUp()}>DIV1</div>
        )
    }
}

五、总结

  1. class类是基于原型的继承的语法糖
  2. class的出现使得代码更加优雅,代码量减少
  3. class类能清晰的指定构造函数和抽象方法
  4. class类在声明时就可以设定属性和方法,不需要再往函数的原型中添加方法
  5. 使用class类时必须实例化
  6. 使用extends关键字实现继承
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值