欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

es6类class

程序员文章站 2022-03-08 22:16:46
...

es5之前定义对象类

function Person(name,age){
    this.name = name
    this.age = age
}

Person.prototype.showName = function(){
    console.log(this.name)
}
Person.prototype.showAge = function(){
    console.log(this.age)
}
或
Object.assign(Person.prototypr,{
    showName = function(){
        console.log(this.name)
    },
    showAge = function(){
        console.log(this.age)
    }
})

let p = new Person("张三",18)
p.showName()
p.showAge()

es6 采用关键字class来定义类:

class Person{
    constructor(name,age){ // 构造函数,只要调用了new 就会执行这个函数
        console.log("构造函数执行了")
        this.name = name
        this.age = age
    }
    //注意:方法之间不能有逗号,他不是一个json,是有一个类
    showName(){
        console.log(this.name)
    }
    showAge(){
        console.log(this.age)
    }
}

或表达式定义class类:
const Person = class{
    constructor(name,age){ // 构造函数,只要调用了new 就会执行这个函数
        console.log("构造函数执行了")
        this.name = name
        this.age = age
    }
    showName(){
        console.log(this.name)
    }
    showAge(){
        console.log(this.age)
    }
}

let p = new Person("张三",18)
p.showName()
p.showAge()

es6里面属性名可以放表达式:

let Fun = "showF"   // 定义一个变量
class Person{
    constructor(name,age){ // 构造函数,只要调用了new 就会执行这个函数
        console.log("构造函数执行了")
        this.name = name
        this.age = age
    }
    //注意:方法之间不能有逗号,他不是一个json,是有一个类
    showName(){
        console.log(this.name)
    }
    showAge(){
        console.log(this.age)
    }
    [Fun](){
        console.log("变量方法")
    }
}
let p = new Person("张三",18)
p.showF() 等同于 p[Fun]()

也可以使用字符串拼接 [a+b](){}   p[a+b]()

注意:1.ES6中class类不支持提升的功能(预解析),在ES5中函数定义的类能够先执行后定义,但是class类只能先定义再执行

2.ES里面的this比之前轻松

矫正this的方法:

1.fn.call(this指向谁,args1,args2....)  // 单个传参
2.fn.call(this指向谁,[args1,args2....]) // 数组形式传参
3.fn.bind(this指向谁) // 只进行this矫正,不传参

正常情况下this指向不会发生改变,但是有时候我们会用到ES6解构语法,来获取勒种的方法,name此时this就发生了变化:

class Person{
    constructor(name,age){ 
        this.name = name
        this.age = age
        this.showName = this.showName.bind(this) // 重定向this
    }
    showName(){
        console.log(this.name)
    }
    showAge(){
        console.log(this.age)
    }
}
let p = new Person("张三",18)
let{showName} = p;
showName()  // 此时使用解构出来的函数会报错,this,解决的方法是在构造函数中,重新定向this,如上。

class里面取值函数getters,存值函数setter:

class Person{
    constructor(){ 

    }
    get name(){
        console.log(`获取了name属性:${this.name}`)
    }
    set name(){
        console.log(`设置了name属性:${this.name}`)
    }
}
let p = new Person()
p.name = "张三" // 设置name
console.log(p.name) // 获取name

注:一般用于封装底层的插件才会用到getter和setter

class静态方法:

class Person{
    constructor(name){ 
        this.name = name
        this.showName = this.showName.bind(this) // 重定向this
    }
    showName(){
        console.log(this.name)
    }
    static  aaa(){ // 声明静态方法,可以在外部通过类对象调用
        // 封装插件时用的比较多,比如jQuery.fn()
        console.log(`这是静态方法`)
    }
}
let p = new Person("张三")

console.log(Person.aaa())  // 如果没有声明静态方法时,这样调用就会报错

类的继承:

之前类的继承:
父类:
function Persong(name){
    this.name = name
}
Person.prototype.showName = function(){
    console.log(`名字是:${this.name}`)
}
子类:
function Student(name,done){
    Person.call(this,name) // 继承父级的属性
    this.done = done
}
Student.prototypr = new Persin(); // 继承父级方法(此时需要矫正constructor)

调用:

let stud1 = new Student("小明","读书")
console.log(stud1.showName())

class中的继承:
父类
class Person{
    constructor(name){
        this.name = name
    }
    showName(){
        console.log(this.name)
    }
}
子类
class Student extends Person{ // extends继承
    constructor(name,done){
        super(name) // 执行父级的构造函数
        this.done = done
    }
    showDone(){
        console.log(this.done)
    }
}
调用
let stud1 = new Student("小明","读书")
console.log(stud1.showName())
console.log(stud1.showDone())

如果此时子类中有一个方法名与父级重名,那么会覆盖父级的方法,可以在子类的方法中执行以下父级的方法:
showName(){
    super.showName() // 父级的方法执行
    console.log("子类的showName")
}

es6继承小例子:拖拽

<html>
    <div id="div1">1</div>
    <div id="div2">2</div>
</html>
<script>
    // 普通拖拽(父类)
    class Drag{
        constructor(id){
            this.oDiv = document.querySelector(id)
            this.disx = 0
            this.disy = 0
            this.init()
        }
        init(){
            this.oDiv.onmouseDown = function(ev){         // 鼠标在元素上按下时
            this.disx = ev.clientX - this.oDiv.offsetLeft //鼠标点击时与物体左边的距离
            this.disy = ev.clientY - this.oDiv.offsetTop  // 鼠标点击时与物体右边的距离
            document.onmousemove = this.fnMove.bind(this) // 鼠标移动事件
            document.onmouseup = this.fnUp.bind(this)     // 鼠标抬起事件
            return false; // 阻止默认事件(如:文字选中等)
        }.bind(this)
        fnMove(ev){
            this.oDiv.style.left = ev.clientX - this.disx + "px"
            this.oDiv.style.top= ev.clientY - this.disy + "px"
        }
        fnUp(){null
            document.onmousemove = null
            document.onmoudown = null
        }
    }

    //限定范围拖拽(子类)
    class LimitDrag extends Drag{
        fnMove(ev){
            super.fnMove(ev) // 继承执行父级鼠标移动的方法
            //增加限制范围(只写了水平方向的限制,垂直方向的同理)
            if(this.oDiv.style.left<=0){
                this.oDiv.style.left = 0
            }
            if(this.oDiv.style.left>=500){
                this.oDiv.style.left = 500 + "px"
            }
        }
    }
    // 调用
    new Drag("#div1") // 普通拖拽
    new LimitDrag("#div2") // 限定范围拖拽

</script>

 

相关标签: class