JavaScript-ES6类和对象

在 ES6 之前如何定义一个类,通过构造函数来定义一个类

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>JavaScript-ES6类和对象</title>
    <script>
        function Person() {
            // 实例属性
            this.name = "BNTang";
            this.age = 34;

            // 实例方法
            this.say = function () {
                console.log(this.name, this.age);
            }
        }

        let p = new Person();
        p.say();
    </script>
</head>
<body>
</body>
</html>

如果想要在创建对象的时候就可以指定对应属性的值可以在构造函数中指定形参如下,这是之前介绍的内容

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>JavaScript-ES6类和对象</title>
    <script>
        function Person(name, age) {
            // 实例属性
            this.name = name;
            this.age = age;

            // 实例方法
            this.say = function () {
                console.log(this.name, this.age);
            }
        }

        let p = new Person("BNTang", 23);
        p.say();
    </script>
</head>
<body>
</body>
</html>

在之前的文章当中介绍了构造函数其实也是一个对象,那么就也可以给构造函数动态添加属性和方法,这种动态添加的属性和方法属于静态属性和静态方法需要通过构造函数进行使用如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>JavaScript-ES6类和对象</title>
    <script>
        function Person() {
            // 实例属性
            this.name = "BNTang";
            this.age = 34;

            // 实例方法
            this.say = function () {
                console.log(this.name, this.age);
            }

            // 静态属性
            Person.num = 666;

            // 静态方法
            Person.run = function () {
                console.log("run");
            }
        }

        let p = new Person();
        p.say();
        console.log(Person.num);
        Person.run();
    </script>
</head>
<body>
</body>
</html>

从 ES6 开始系统提供了一个名称叫做 class 的关键字,这个关键字就是专门用于定义类的

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>JavaScript-ES6类和对象</title>
    <script>
        class Person {
            // 实例属性
            name = "BNTang";
            age = 34;

            // 实例方法
            say() {
                console.log(this.name, this.age);
            }
        }

        let p = new Person();
        p.say();
    </script>
</head>
<body>
</body>
</html>

如果想要在创建对象的时候和之前一样可以指定对应的属性值可以通过一个 constructor 的东西来进行指定,当我们通过 new 创建对象的时候,系统会自动调用 constructor,constructor 我们称之为构造函数

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>JavaScript-ES6类和对象</title>
    <script>
        class Person {
            // 实例属性
            constructor(name, age) {
                this.name = name;
                this.age = age;
            }

            // 实例方法
            say() {
                console.log(this.name, this.age);
            }
        }

        let p = new Person("BNTang", 23);
        p.say();
    </script>
</head>
<body>
</body>
</html>

看了如上的实例属性和方法之后那么 ES6 该如何定义静态属性与方法呢,静态属性与方法是属于类的,在 ES6 中可以通过一个关键字 static 来进行修饰属性与方法被修饰的属性与方法就称之为静态属性与方法,一目了然如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>JavaScript-ES6类和对象</title>
    <script>
        class Person {
            // 实例属性
            constructor(name, age) {
                this.name = name;
                this.age = age;
            }

            // 实例方法
            say() {
                console.log(this.name, this.age);
            }

            // 静态属性
            static num = 666;

            // 静态方法
            static run() {
                console.log("run");
            }
        }

        let p = new Person("BNTang", 23);
        p.say();
        console.log(Person.num);
        Person.run();
    </script>
</head>
<body>
</body>
</html>

ES6 类和对象注意点

第一点,如上定义 "静态属性" 的方式并不是 ES6 正式版标准中的写法,大部分的浏览器不支持,在 ES6 标准中添加实例属性都需要在 constructor 中添加

image-20210908150750851

如上定义 "静态属性" 的方式并不是 ES6 正式版标准中的写法,大部分的浏览器不支持,在 ES6 标准中 static 只支持定义静态方法不支持定义静态变量,还是只能通过之前的方式进行定义如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>ES6类和对象注意点</title>
    <script>
        class Person {
            // 静态方法
            static run() {
                console.log("run");
            }
        }

        // 静态属性
        Person.num = 666;
        let p = new Person();
        console.log(p);
    </script>
</head>
<body>
</body>
</html>

看完了如上两个注意点之后,如下有一段代码是 ES6 之前的语法实现的

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>ES6类和对象注意点</title>
    <script>
        function Person(name, age) {
            // 实例属性
            this.name = name;
            this.age = age;

            // 实例方法
            this.hi = function () {
                console.log("hi");
            }
        }

        // 原型上的方法
        Person.prototype.say = function () {
            console.log(this.name, this.age);
        }

        let p = new Person("BNTang", 34);
        console.log(p);
    </script>
</head>
<body>
</body>
</html>

浏览器运行效果如下图所示

image-20210908153855297

现在利用 ES6 的语法来进行实现和如上一样的结构废话不多说,先上代码看了代码之后在解释我的目的

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>ES6类和对象注意点</title>
    <script>
        class Person {
            constructor(myName, myAge) {
                this.name = myName;
                this.age = myAge;
                this.hi = function () {
                    console.log("hi");
                }
            }

            say() {
                console.log("hi");
            }
        }

        let p = new Person("BNTang", 34);
        console.log(p);
    </script>
</head>
<body>
</body>
</html>

浏览器运行效果图如下

image-20210908154522477

两块代码进行比较,我的目的就是想让你知道 ES6 的语法相当于与 ES6 之前的的那块,ES6 写在 constructor 中的属性和方法保存在实例对象当中,写在 constructor 外部就保存在原型对象当中

image-20210908154717914

了解了如上的几个注意点,下面还有一个注意点需要介绍,查看如下代码我用 ES6 之前的方式定义了一个 Person 类,如果想要在 Person 类的原型对象上保存属性和方法在 ES6 之前有两种方案,第一种方案如下所示就是动态的进行添加属性和方法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>ES6类和对象注意点</title>
    <script>
        function Person(name, age) {
            // 实例属性
            this.name = name;
            this.age = age;
            
            // 实例方法
            this.hi = function () {
                console.log("hi");
            }
        }

        // 原型上的方法
        Person.prototype.type = "人";
        Person.prototype.say = function () {
            console.log(this.name, this.age);
        };

        let person = new Person();
        console.log(person);
    </script>
</head>
<body>
</body>
</html>

image-20210908160741429

如上就是在 ES6 之前给类的原型对象添加属性和方法的第一种方案,在来介绍第二种,第二种就是自定义原型对象代码如下所示

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>ES6类和对象注意点</title>
    <script>
        function Person(name, age) {
            // 实例属性
            this.name = name;
            this.age = age;

            // 实例方法
            this.hi = function () {
                console.log("hi");
            }
        }

        Person.prototype = {
            constructor: Person,
            type: "人",
            say: function () {
                console.log(this.name, this.age);
            }
        };

        let person = new Person("BNTang", 23);
        console.log(person);
    </script>
</head>
<body>
</body>
</html>

image-20210908161139309

如上是 ES6 之前类和对象的定义方式和给原型对象添加属性和方法的方案,接下来就利用 ES6 的方式来演变一下这个过程顺便也可以把要介绍的注意点也可以引出来,先来看第一种方案的演变,经过之前的内容介绍到利用 ES6 语法中的 constructor 定义属性和方法是属于实例的,写在 constructor 外面的是属于原型对象的,但是写在 constructor 外面的属性想要保存在原型对象上是不行的,那么只能动态的进行添加了代码如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>ES6类和对象注意点</title>
    <script>
        class Person {
            constructor(name, age) {
                this.name = name;
                this.age = age;
                this.hi = function () {
                    console.log("hi");
                }
            }

            run() {
                console.log("run");
            }
        }

        Person.prototype.type = "人";
        Person.prototype.say = function () {
            console.log(this.name, this.age);
        };
        
        let p = new Person("BNTang", 34);
        console.log(p);
    </script>
</head>
<body>
</body>
</html>

image-20210908162411172

如上代码看了动态添加属性和方法之后在来看看自定义原型对象的方式进行添加属性和方法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>ES6类和对象注意点</title>
    <script>
        class Person {
            constructor(name, age) {
                this.name = name;
                this.age = age;
                this.hi = function () {
                    console.log("hi");
                }
            }

            run() {
                console.log("run");
            }
        }

        let obj = {
            constructor: Person,
            type: "人",
            say: function () {
                console.log(this.name, this.age);
            }
        };
        Person.prototype = obj;

        let p = new Person("BNTang", 34);
        console.log(p);
    </script>
</head>
<body>
</body>
</html>

image-20210908175121780

通过如上运行的结果图发现,自定义的原型对象没有设置成功,如果通过 ES6 class 定义类,那么就不能自定义这个类的原型对象,如果想将属性和方法保存到原型中,只能动态给原型对象添加属性和方法,不能自定义原型对象的原因很简单,如果你自定义了原型对象那么在 class 定义的类中添加的方法就会造成添加不到 class 定义的类的原型对象当中了,这个就是要介绍的注意点🐂

posted @ 2021-09-07 20:01  BNTang  阅读(80)  评论(0编辑  收藏  举报