JS-类和对象

面向对象

(1)定义:
①面向过程变成POP:面向过程就是分析出解决问题需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候再一个一个依次调用。
②面向对象变成OOP:把事物分解成一个个对象,然后由对象之间分工合作。
(2)对比:
①面向过程:优点:性能比面向对象高,适合跟硬件联系很紧密的东西,例如单片机采用面向过程编程。缺点:没有面向对象易维护、易复用、易扩展。
②面向对象:优点:易维护、易复用、易扩展,由于三特性可以设计出低耦合性的系统,使系统更灵活。缺点:性能比面向过程低。
(3)面向对象特点:面向对象编程具有灵活、代码可复用、容易维护和开发的优点,适合多人合作的大型项目。具有封装性、继承性和多态性。
(4)面向对象的思维特点:①抽取对象共用的属性和行为封装成一个类;②对类实例化,获取类的对象。
(5)对象:在JavaScript中,对象是一组无序的相关属性和方法的集合,所有的事物都是对象(字符串、数值、数组、函数),由属性和方法组成。

(1)类的定义:可以使用class关键字声明一个类,之后以这个类来实例化对象。
(2)利用类创建对象:通过class关键字创建类,类名习惯性首字母大写;类里面有constructor函数,可以接受传递过来的参数,同时返回实例对象。

// constructor方法是类的构造方法(默认方法),用于传递参数,返回实例对象,通过new命令生成对象实例时,自动调用该方法。如果没有显示定义,类内部会自动给我们创建一个constructor()
// 创建类star
class Star {
    // 类的共有属性放到constructor里面
    constructor(uname) {
    this.uname = uname;
    this.age = age;
     }
     sing(song) {
    console.log(this.uname+song);
      }
}

// 利用类创建对象
var xz = new Star('肖战',18);
console.log(xz);
xz.sing('满足');

// 过程分析:在new创建对象时自动调用constructor构造函数,将对象传入的参数'肖战'传给形参uname,然后uname指向this.uname,此时this指向创建的实例。故这个时候实例中就有uname属性了。

(3)类的继承:子类可以继承父类的一些属性和方法。

        // 定义一个Father类
        class Father {
            constructor() {

            }
            money() {
                console.log('jicheng')
            }
        }
        // Son类继承Father类
        class Son extends Father {

        }
        var son = new Son();
        son.money();

(4)super关键字
①super关键字用于访问和调用父类上的函数,可以调用父类的构造函数,也可以调用父类的普通函数。
②super关键字用于访问和调用对象父类上的函数。可以调用父类的构造函数,也可以调用父类的普通函数。

// 1. 当子类调用父类构造函数并传递参数时,需用到super关键字

// 定义一个Father类
        class Father {
            constructor(x,y) {
                this.x = x;
                this.y = y;
            }
            sum() {
                console.log(this.x + this.y)
            }
        }
        // Son类继承Father类
        class Son extends Father {
            constructor(x,y) {
                super(x,y); // 调用了父类中的构造函数
            }
        }
        var son = new Son(1,2);
        son.sum();
// 2. 调用父类的普通函数

class Father {
            say() {
                return '我是爸爸'
            }
        }
        class Son extends Father {
            say() {
                console.log(super.say() + '的儿子')
            }
        }
        var son = new Son();
        son.say();
// 3.子类继承父类加法方法时,同时扩展减法方法
// 定义一个Father类
        class Father {
            constructor(x,y) {
                this.x = x;
                this.y = y;
            }
            sum() {
                console.log(this.x + this.y)
            }
        }

class Son extends Father {
            constructor(x,y) {
                // 子类继承父类加法方法时,同时扩展减法方法
                super(x,y) 
                // super必须在this前面(必须先调用父类的构造方法,再使用子类的方法)
                this.x=x;
                this.y=y;
            }
            substract() {
                console.log(this.x-this.y);
            }
        }
        var son = new Son(5,3);
        son.substract();
        son.sum();

(5)三个注意点
①在ES6中没有变量提升,所以必须先定义类,才能通过类实例化对象
②类里面共有的属性和方法一定要加this使用
③类里面this的指向问题:constructor里面的this指向实例对象,方法里面的this指向这个方法的调用者

<button>点击</button>

<script>
class Star {
            constructor(uname,age) {// constructor的作用是创建一个实例,故里面的this指向创建的实例
                console.log(this);
                // 页面加载后this打印结果:Star {}age: undefinedbtn: buttonuname: "xiaozhan"__proto__: Object
                this.uname = uname;
                this.age = age;
                this.btn = document.querySelector('button')
                this.btn.onclick = this.sing; // 函数this.sing不能加(),若加了会立即执行而不是点击按钮后再执行
                // 点击按钮后打印:<button>点击</button>
                this.dance()
            }
            sing() {
                console.log(this);
                // 此时打印的this,指向button,因为是button调用的
                console.log(this.uname);
                // 此时打印的this.uname是undefined,因为button没有uname属性
            }
            dance() {
                // 此时打印的this,谁调用指向谁(此时指向xz,因为是xz调用dance()方法)
                console.log(this)
            }
        }
        var xz = new Star('xiaozhan')
        xz.dance() // 打印结果:Star {uname: "xiaozhan", age: undefined, btn: button}
</script>

若想点击按钮时调用constructor中的this,可增加一个that变量

<button>点击</button>

<script>
        var that
        class Star {
            constructor(uname,age) {// constructor的作用是创建一个实例,故里面的this指向创建的实例
                console.log(this);
                // 页面加载后this打印结果:Star {}age: undefinedbtn: buttonuname: "xiaozhan"__proto__: Object
                that = this
                this.uname = uname;
                this.age = age;
                this.btn = document.querySelector('button')
                this.btn.onclick = this.sing; // 函数this.sing不能加(),若加了会立即执行而不是点击按钮后再执行
                // 点击按钮后打印:<button>点击</button>
                this.dance()
            }
            sing() {
                console.log(this);
                // 此时打印的this,指向button,因为是button调用的
                console.log(that.uname); // that存储的是constructor里面的this
                // 此时打印的this.uname是undefined,因为button没有uname属性
            }
            dance() {
                // 此时打印的this,谁调用指向谁(此时指向xz,因为是xz调用dance()方法)
                console.log(this)
            }
        }
        var xz = new Star('xiaozhan')
        xz.dance() // 打印结果:Star {uname: "xiaozhan", age: undefined, btn: button}
    </script>
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容