JavaScript面向对象

JavaScript 并不严格地要求使用对象,甚至可以不使用函数,将代码堆积成简单的顺序代码流。但随着代码的增加,为了提供更好的软件复用,建议使用对象和函数。

面向对象的概念

JavaScript 并不是面向对象的程序设计语言,面向对象设计的基本特征:继承、多态等没有得到很好的实现。在纯粹的面向对象语言里,最基本的程序单位是类,类与类之间提供严格的继承关系。比如 Java 中的类,所有的类都可以通过 extends 显式继承父类,或者默认继承系统的 Object 类。而 JavaScript 并没有提供规范的语法让开发者定义类。

对象和关联数组

当需要访问某个 JavaScript 对象的属性时,不仅可以使用 obj.propName 的形式 , 也 可以采用 obj[propName]的形式, 有些时候甚至必须使用这种形式。

    <script>
        function Person(name,age){
            this.name=name;
            this.age=age;
            this.info=function(){
                alert("info");
            }
        }
        var p = new Person('小明',19);
        for(proName in p){
            document.write('p 对象的'+proName+"属性值:"+p[proName]+'<br/>');
            document.write('p 对象的'+proName+"属性值:"+p.proName+'<br/>');
        }
    </script>

运行结果:
p 对象的name属性值:小明
p 对象的name属性值:undefined
p 对象的age属性值:19
p 对象的age属性值:undefined
p 对象的info属性值:function(){ alert(“info”); }
p 对象的info属性值:undefined

原因分析:用p.proName 的形式, JavaScript 不会把 propName 当成变量处理, 它试图直接访问该对象的 propName 属性一但该属性实际并不存在。

继承和 prototype

问题导入:

     function Person(name,age){
            this.name=name;
            this.age=age;
            this.info=function(){
                alert("info");
            }
        }

原来方法为 Person 类定义增加 info 方法相当不好,主要有如下两个原因。

  • 性能低下: 因为每次创建 Person 实例时,程序依次向下执行,每次执行程序中都将创建一个新的 info 函数一当创建多个 Person 对象时,系统就会有很多个 info 函数-~这就会造成系统内存泄涌,从而引起性能下降。实际上, info 函数只需 要一个就够了 。
  • 使得 info 函数中的局部变量产生闭包: 闭包会扩大局部变握的作用域,使得局部变量 一直存活到函数之外的地方

改善方法把(函数定义在类外):

伪继承机制:

JavaScript 的所有类(也就是函数)都有一个 prototype 属性, 如果为 JavaScript类的 prototype 属性增加属性、 方法,则可视为对原有类的扩展。 我们可理解为: 增加了 prototype 属性的类继承了原有的类-这就是 JavaScript 所提供的一种伪继承机制 。
代码示例:

  <script>
        function Person(name,age){
            this.name = name;
            this.age = age;
            this.info = function(){
                document.write("姓名"+this.name+'<br/>');
                document.write("年龄"+this.age+'<br/>');
            }
        } 
        var p1 = new Person('li',19);
        p1.info();
        // 把work方法增加到Person的prototype属性上
        // 动态增加,即使p1现在没有work方法,下面定义了之后,在后面也可以调用
        Person.prototype.work = function(){
            document.write(this.name+"玩呢。。。<br/>");
        }  
        document.write('<hr/>');
        var p2 = new Person('liu',20);
        p2.info();
        document.write('<hr/>');
        p2.work();
        // p1可以调用work方法
        p1.work();
    </script>

但这种“伪继承"的实质是修改了原有的类, 并不是 产生了一个新的子类

prototype 属性为该类创建对象

JavaScript 类的 prototype 属性代表了该类的原型对象。在默认情况下, JavaScript 类的 prototype 属性值是一个 Object 对象,将 JavaScript 类的 prototype 设为父类实例,可实现 JavaScript 语言的继承。
代码示例:

    <script>
        function Person(name,age){
            this.name = name;
            this.age = age;
        }
        //使用 prototype 为 Person 类添加 sayHello 方法 
        Person.prototype.sayHello=function(){
            console.log(this.name+'向你打招呼');
        }
        var per = new Person('牛魔王',22);
        per.sayHello();//输出,牛魔王向你打招呼
        function Student(grade){
            this.grade = grade;
        }
        //将 Student的 prototype 设为 Person 对象 
        Student.prototype = new Person('未命名',0);
        Student.prototype.intro = function(){
            console.log("%s是个学生,读%d年级",this.name,this.grade);
        }
        var stu = new Student(5);
        alert(stu.name);
        stu.name = "孙悟空";
        console.log(stu instanceof Student);//true
        console.log(stu instanceof Person);//true
        stu.sayHello();//输出 : 孙悟空向您打招呼 !
        stu.intro();//输出 : 孙悟空是个学生,读 5 年级 
    </script>

使用 apply 或 call 实现伪继承

  <script>
        function Person(name,age){
            this.name = name;
            this.age = age;
        }
        //使用 prototype 为 Person 类添加 sayHello 方法 
        Person.prototype.sayHello=function(){
            console.log(this.name+'向你打招呼');
        }
        var per = new Person('牛魔王',22);
        per.sayHello();//输出,牛魔王向你打招呼
        function Student(name,age,grade){
            // Person.call(this,name,age);
            Person.apply(this,[name,age]);
            this.grade = grade;
        }
        //使用 prototype 为 Student 类添加 intro 方法 
        Student.prototype.intro = function(){
            console.log("%s是个学生,读%d年级",this.name,this.grade);
        }
        var stu = new Student('孙悟空',34,5);
        console.log(stu instanceof Student);//true
        console.log(stu instanceof Person);//伪继承,所以输出 false 
        stu.sayHello();//输出 : 孙悟空向您打招呼 !
        stu.intro();//输出 : 孙悟空是个学生,读 5 年级 
    </script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值