• JS三大特性


    抽象

    在分析三大特性之前我们要先了解什么叫抽象。

    定义:

    在定义一个类的时候,实际上就是把一类事物的共有的属性和行为提取出来,形成一个物理模型(模板),这种研究问题的方法就称为抽象

    一、封装

    定义:

    就是把抽象出来的属性和对属性的操作封装在一起,属性被保护在内部,程序的其他部分只能通过特定的操作(函数),才能对属性进行操作。

    公开属性和私有属性

    <script>
    
        function Person(in_name, in_age, in_sql) {
            this.name = in_name;
            var age = in_age;
            var sql = in_sql;
        }
    
        var p1 = new Person("haha", 20, 1000)
        alert(p1.name)
    
    </script>

    结果:

    image

    但是此时我们访问,age和sql:

    <script>
    
        function Person(in_name, in_age, in_sql) {
            this.name = in_name;
            var age = in_age;
            var sql = in_sql;
        }
    
        var p1 = new Person("haha", 20, 1000)
        alert(p1.age)
    
    </script>

    结果:

    image

    说明:

    这里我们就看到了name是公开属性,而age和sql则是私有属性

    问题:属性有公开属性和私有属性,那方法有没私有和公开之分那?

    类中的公开方法有个别名特权方法,私有方法有个别名内部方法

    公开方法

    <script>
    
            function Person(in_name, in_age, in_sql) {
                this.name = in_name;  // 公开属性
                var age = in_age;  // 私有属性
                var sql = in_sql;  // 私有属性
    
                // 在类中如何定义公开方法(特权方法);私有方法(内部方法)
                // 如果我们希望操作私有的属性,则可用公开方法实现
                this.show = function () {
                    alert(age + "" + sql)
                }
            }
    
            var p1 = new Person("haha", 20, 1000)
            p1.show();
    
        </script>
    公开方法

    结果:

    image

    说明:

    外部要想操作私有属性,可以通过公开方法来实现

    私有方法

    <script>
    
            function Person(in_name, in_age, in_sql) {
                this.name = in_name;  // 公开属性
                var age = in_age;  // 私有属性
                var sql = in_sql;  // 私有属性
    
                // 私有方法
                function show2() {
                    alert(age + ' ' + sql)
                }
    
            }
    
            var p1 = new Person("haha", 20, 1000)
            p1.show2();  // 这样调用会报错!
    
        </script>
    私有方法

    说明:

    私有方法同样可以使用同 中的私有属性,但是私有方法在外部却无法被操作。

    上面的方法,在每次实例化对象的时候,会为每个对象生成一次,即每个对象中都有一个类似的方法,在一定程度上会造成资源浪费。

    原型对象 prototype

    因此我们想到 原型对象(prototype) 的基础上添加方法,间接的效果也让让每个对象也具有这个方法,这样操作只让方法在类中存一份,不会在每个对象中储存。

    但是这个样处理,也有小问题;即不能调用私有变量和私有方法。

    定义的方法操作公有属性:

    <script>
    
            function Person() {
                this.name = "abc";
                var age = 90;
            }
    
            Person.prototype.fun1 = function() {
                alert(this.name);
            }
    
            var p1 = new Person();
            p1.fun1();  // 结果:弹出abc
    
        </script>
    公有属性

    定义的方法操作私有属性:

    <script>
    
            function Person() {
                this.name = "abc";
                var age = 90;
            }
    
            Person.prototype.fun1 = function() {
                alert(age);
            }
    
            var p1 = new Person();
            p1.fun1();  // 结果:报错 age is not defined(…)
    
        </script>
    私有属性

    操作私有方法和公有方法:

    <script>
    
            function Person() {
                this.name = "abc";  // 公有属性
                var age = 90;  // 私有属性
                // 共有方法
                this.show1 = function() {
                    alert("haha")
                }
                // 私有方法
                function show2() {
                    alert("xxx")
                }
            }
    
            Person.prototype.fun1 = function() {
                this.show1();  // 正确
    
                show2();  // 报错
            }
    
            var p1 = new Person();
            p1.fun1();
    
        </script>
    操作方法

    二、继承

    问题:为什么需要继承?

    最直接的回答,解决代码冗余。

    需求:学生交学费,中学生打8折;小学生打5折,然后通过打印的方法,显示学生的名字、年龄记应缴学费。

    我们初步的代码:

    <script>
            // 中学生
            function MidStu(name,age) {
                this.name = name;
                this.age = age;
                this.show = function() {
                    alert(this.name + ' ' + this.age);
                }
    
                // 计算学费
                this.payFee = function(mon) {
                    alert("应缴" + mon*0.8);
                }
            }
    
            // 小学生
            function PupStu(name,age) {
                this.name = name;
                this.age = age;
                this.show = function() {
                    alert(this.name + ' ' + this.age);
                }
    
                // 计算学费
                this.payFee = function(mon) {
                    alert("应缴" + mon*0.5);
                }
            }
    
        </script>

    可以看出两个类型学生代码中有很多相同的代码,出现了代码冗余的问题。

    问题:怎么解决上面的代码冗余?

    抽象出一个学生类(即,把两类学生共性取出来形成的类);然后通过继承的方式处理。

    <script>
            // 抽象出两类学生共性的类
            function Stu(name, age) {
                this.name = name;
                this.age = age;
                this.show = function() {
                    alert(this.name + ' ' + this.age);
                }
            }
    
            // 中学生
            function MidStu(name,age) {
                // js实际上是通过对象冒充来实现继承的。
                this.stu = Stu;
                this.stu(name, age);  // 这段代码很重要,如果没有它则继承就失败了
    
                // 计算学费
                this.payFee = function(mon) {
                    alert("应缴" + mon*0.8);
                }
            }
    
            // 小学生
            function PupStu(name,age) {
                this.stu = Stu;
                this.stu(name, age);
    
                // 计算学费
                this.payFee = function(mon) {
                    alert("应缴" + mon*0.5);
                }
            }
    
            // 测试继承
            var midStu = new MidStu("haha", 30);
            midStu.show();
    
        </script>
    继承

    结果:

    image

    结果我们发现,我们的MidStu中并没show方法,但是我们结果却能调用。

    说明:

    js的继承实际上是通过对象冒充来实现的。

    js对象继承的关键点:

    • this.stu = Stu;这里相当于将整个Stu函数赋值给stu;赋值的是内存中的索引。此时如果alert(this.stu)的话;会将Stu的整个函数打印出来
    • image
    • this.stu(‘xxx’, 20):这段代码相当重要,关乎继承能否成功,前面我们知道,第一步只是接收了Stu的内存中的索引,这步的执行,就相当于将Stu的属性和方法,具体的赋给MidStu。

    总结:

    1、这里体现了js是动态语言的特性,在执行的过程中开辟内存空间。

    2、js的继承是通过对象冒充来完成的。

    3、js可以实现多重继承,虽然很少用,但是它具备这个功能。

    4、Object类是js所有类的基类。

    多态

    定义:

    指一个引用(类型)在不同情况下的多种状态。

    js实际上是舞台的,是一种动态语言,一个变量的类型是在运行的过程中有js引擎来决定的,所以,也可以说js天生就支持多态。

    典型案例:

    <script>
    
            function Person() {
                this.test = function() {
                    alert("Person");
                }
            }
    
            function Dog() {
                this.test = function() {
                    alert("Dog");
                }
            }
    
            var v = new Person();
            alert(v.constructor);
    
            v = new Dog();
            alert(v.constructor);
    
        </script>
    多态

    通过打印对象的构造函数来判断对象的类型。v会随着对象的创建,而变化类型。

  • 相关阅读:
    demo04-默认标签
    demo03-段落标签
    demo02-标题标签
    demo01-注释标签
    前端基础介绍
    xadmin的详细使用
    设置Linux环境变量中文显示乱码
    ES应用
    HTTP协议
    jboss
  • 原文地址:https://www.cnblogs.com/jayafs/p/6219466.html
Copyright © 2020-2023  润新知