JavaScript的面向对象

一、面向对象的概述

  ECMAScript 有两种开发模式:1.函数式(过程化),2.面向对象(OOP)。

  面向对象的语言有一个标志,那就是类的概念,而通过类可以创建任意多个具有相同属性和方法的对象。

  但是,ECMAScript 没有类的概念,因此它的对象也与基于类的语言中的对象有所不同。

  js是基于对象,不是面向对象的。不具备描述事物的能力。

   1、创建一个对象,然后给这个对象新建属性和方法

  var box = new Object();             //创建一个 Object 对象
    box.name = ‘Lee‘;                     //创建一个 name 属性并赋值
    box.age = 100;                         //创建一个 age 属性并赋值
    box.run = function () {             //创建一个 run()方法并返回值
        return this.name + this.age + ‘运行中...‘;
    };
    alert(box.run());                     //输出属性和方法的值

    上面创建了一个对象,并且创建属性和方法,在 run()方法里的 this,就是代表 box 对象本身。

    这种是 JavaScript 创建对象最基本的方法,但有个缺点,想创建一个类似的对象,就会产生大量的代码。

  var box = new Object();             //创建一个 Object 对象
    box.name = ‘Lee‘;                     //创建一个 name 属性并赋值
    box.age = 100;                         //创建一个 age 属性并赋值
    box.run = function () {             //创建一个 run()方法并返回值
        return this.name + this.age + ‘运行中...‘;
    };
    alert(box.run());                     //输出属性和方法的值

    var box2 = box;                 //得到 box 的引用
    box2.name = ‘Jack‘;                 //直接改变了 name 属性
    alert(box2.run());                 //用 box.run()发现 name 也改变了

    var box2 = new Object();
    box2.name = ‘Jack‘;
    box2.age = 200;
    box2.run = function () {
        return this.name + this.age + ‘运行中...‘;
    };
    alert(box2.run());                 //这样才避免和 box 混淆,从而保持独立

    为了解决多个类似对象声明的问题,我们可以使用一种叫做工厂模式的方法,这种方法就是为了解决实例化对象产生大量重复的问题。

  function createObject(name, age) { //集中实例化的函数
        var obj = new Object();
        obj.name = name;
        obj.age = age;
        obj.run = function () {
            return this.name + this.age + ‘运行中...‘;
        };
        return obj;
    }
    var box1 = createObject(‘Lee‘, 100); //第一个实例
    var box2 = createObject(‘Jack‘, 200); //第二个实例
    alert(box1.run());
    alert(box2.run()); //保持独立

    工厂模式解决了重复实例化的问题,但还有一个问题,那就是识别问题,因为根本无法搞清楚他们到底是哪个对象的实例。

  function createObject(name, age) { //集中实例化的函数
        var obj = new Object();
        obj.name = name;
        obj.age = age;
        obj.run = function () {
            return this.name + this.age + ‘运行中...‘;
        };
        return obj;
    }
    var box1 = createObject(‘Lee‘, 100); //第一个实例
    var box2 = createObject(‘Jack‘, 200); //第二个实例
    alert(box1.run());
    alert(box2.run()); //保持独立

    alert(typeof box1); //Object
    //alert(box1 instanceof box);//不能判断
    alert(box1 instanceof Object); //true    都是Object类型 无法区分谁到底是谁的

  2、第二种创建对象的方式

    ECMAScript 中可以采用构造函数(构造方法)可用来创建特定的对象。类型于 Object 对象(用函数来模拟面对对象的中的描述)。

      //用js来描述人
            function Person(){                    //相当于构造器。
                alert("person run");
            }

            //通过描述进行对象的建立。 new.
            var p  = new Person();
            //动态给p对象添加属性。直接使用p.属性名即可。
            p.name = "zhangsan";
            p.age = 29;
            //如果定义的p对象的属性赋值为一个函数,即是给p对象添加一个方法。
            p.show = function(){
                alert("show :"+this.name+":"+this.age);
            }

            p.show();
    function Box(name,age){
        this.name = name;
        this.age = age;
        this.run = function(){
            return this.name+this.age+"运行中.....";
        }
    }
    var box1 = new Box(‘Lee‘, 100); //new Box()即可
    var box2 = new Box(‘Jack‘, 200);
    alert(box1.run());
    alert(box1 instanceof Box); //很清晰的识别他从属于 Box

使用构造函数的方法,即解决了重复实例化的问题,又解决了对象识别的问题,但问题是,这里并没有 new Object(),为什么可以实例化 Box(),这个是哪里来的呢

使用了构造函数的方法,和使用工厂模式的方法他们不同之处如下:
1.构造函数方法没有显示的创建对象(new Object());但它后台会自动var object = new Object();
2.直接将属性和方法赋值给 this 对象;this就相当于object

3.没有 renturn 语句,构造函数不需要返回对象的引用,它是后台自动返回的

构造函数的方法有一些规范:

1.函数名和实例化构造名相同且大写,(PS:非强制,但这么写有助于区分构造函数和普通函数);

2.通过构造函数创建对象,必须使用 new 运算符。

既然通过构造函数可以创建对象,那么这个对象是哪里来的,new Object()在什么地方执行了?执行的过程如下:

1.当使用了构造函数,并且 new 构造函数(),那么就后台执行了 new Object();
2.将构造函数的作用域给新对象,(即 new Object()创建出的对象),而函数体内的 this 就代表 new Object()出来的对象。
3.执行构造函数内的代码;
4.返回新对象(后台直接返回)。

关于 this 的使用,this 其实就是代表当前作用域对象的引用。如果在全局范围 this 就代表 window 对象,如果在构造函数体内,就代表当前的构造函数所声明的对象。

var box = 2;
alert(this.box); //全局,代表 window

构造函数和普通函数的唯一区别,就是他们调用的方式不同。只不过,构造函数也是函数,必须用 new 运算符来调用,否则就是普通函数(函数名首字母无序大写)。

 function Box(name, age) { //构造函数模式
            this.name = name;
            this.age = age;
            this.run = function () {
            return this.name + this.age + ‘运行中...‘;
        };
    }

    var box = new Box(‘Lee‘, 100); //构造模式调用
    alert(box.run());
  //  Box(‘Lee‘, 20); //普通模式调用,无效

可以使用对象冒充来调用

  function Box(name, age) { //构造函数模式
            this.name = name;
            this.age = age;
            this.run = function () {
            return this.name + this.age + ‘运行中...‘;
        };
    }

    var o = new Object();
    Box.call(o, ‘Jack‘, 200) //对象冒充调用,o这个对象冒充Box对象来运行
    alert(o.run());

探讨构造函数内部的方法(或函数)的问题,首先看下两个实例化后的属性或方法是否相等。

  function Box(name, age) { //构造函数模式
            this.name = name;
            this.age = age;
            this.run = function () {
                return this.name + this.age + ‘运行中...‘;
        };
    }
    var box1 = new Box(‘Lee‘, 100); //传递一致
    var box2 = new Box(‘Lee‘, 100); //同上

    alert(box1.name == box2.name); //true,属性的值相等
    alert(box1.run == box2.run); //false,方法其实也是一种引用地址
    alert(box1.run() == box2.run()); //true,方法的值相等,因为传参一致

可以把构造函数里的方法(或函数)用 new Function()方法来代替,得到一样的效果,更加证明,他们最终判断的是引用地址,唯一性。

  function Box(name, age) {                     //new Function()唯一性
        this.name = name;
        this.age = age;
        this.run = new Function("return this.name + this.age + ‘运行中...‘");
    }
    var box1 = new Box(‘Lee‘, 100); //传递一致
    var box2 = new Box(‘Lee‘, 100); //同上

    alert(box1.name == box2.name); //true,属性的值相等
    alert(box1.run == box2.run); //false,方法其实也是一种引用地址
    alert(box1.run() == box2.run()); //true,方法的值相等,因为传参一致

我们可以通过构造函数外面绑定同一个函数的方法来保证引用地址的一致性,但这种做法没什么必要,只是加深学习了解:

  function Box(name, age) {
        this.name = name;
        this.age = age;
        this.run = run;
    }
    function run() { //通过外面调用,保证引用地址一致
        return this.name + this.age + ‘运行中...‘;
    }
    var box1 = new Box(‘Lee‘, 100); //传递一致
    var box2 = new Box(‘Lee‘, 100); //同上

    alert(box1.name == box2.name); //true,属性的值相等
    alert(box1.run == box2.run); //true,用的是同一个函数,所以地址相同
    alert(box1.run() == box2.run()); //true,方法的值相等,因为传参一致

虽然使用了全局的函数 run()来解决了保证引用地址一致的问题,但这种方式又带来了一个新的问题,全局中的 this 在对象调用的时候是 Box 本身,而当作普通函数调用的时候,this 又代表 window。

二、对象中的成员:

1、js实现私有成员:(在java中,有成员的访问修饰符的概念:private,默认,prototype,public,但是在js中没有,只能模拟出私有成员,即通过作用域不同来体现,一般不这样用阅读性差)

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

        //这是一个局部变量,如果将var去掉就变成全局变量了
        //在js中,通过this把变量和方法与类关联上的,如果自己用var定义了一个变量或者直接定义了一个方法,会认为这个方法或变量与当前的类无关
        //可以被看做是局部的变量和方法
        var sex = "女";

        setSex = function(){
            sex = "男";
        }

        //通过this修饰方法
        //通过成员方法调用局部方法修改局部变量
        this.changeSex = function(){
            setSex();
        }
        //通过成员方法返回局部变量的值
        this.getSex = function(){
            return sex;
        }
    }

    //创建一个对象
    var p = new Person("科比",34);
    //alert(p.name+"****"+p.age);
    //alert(p.sex);//结果是undefined,不能直接访问,
    alert(p.getSex());//女
    p.changeSex();
    alert(p.getSex());

2、给类添加静态的属性和方法

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

        //这是一个局部变量,如果将var去掉就变成全局变量了
        //在js中,通过this把变量和方法与类关联上的,如果自己用var定义了一个变量或者直接定义了一个方法,会认为这个方法或变量与当前的类无关
        //可以被看做是局部的变量和方法
        var sex = "女";

        setSex = function(){
            sex = "男";
        }

        //通过this修饰方法
        //通过成员方法调用局部方法修改局部变量
        this.changeSex = function(){
            setSex();
        }
        //通过成员方法返回局部变量的值
        this.getSex = function(){
            return sex;
        }
    }

    //添加静态属性
    Person.sex = ‘男‘;
    //添加静态方法
    Person.run = function(){
        alert(‘run‘);
    }

    //调用静态属性和静态方法
    alert(Person.sex);
    alert(Person.run());
时间: 2024-10-14 02:18:03

JavaScript的面向对象的相关文章

《JavaScript》——面向对象之原型

上一篇文章我主要介绍的是在JavaScript里对象的创建,可是,在对象的创建过程中有很多知识我们还没有学习,那就是原型,原型式什么东东哪?在这里我想用自己的理解跟大家说说,有不对的地方大家可以给我提意见. 首先说,原型就是对象,这个对象中的属性和方法可以被共享,被谁共享哪?就是被实例们共享(当我们创建一个对象后,然后再用这个对象去实例化许多实例). 我们创建的每个对象都有一个 prototype(原型)属性,这个属性是系统自动创建的,通过这个属性(prototype)就可以直接访问到该对象的原

JavaScript的面向对象编程(OOP)(一)——类

在学习JavaScript面向对象的编程之前,需要知道,并了解面向对象的一些基本的常识.初学者中大多数都以为面向对象中,面向对象的编程是很重要和占据很大一部分精力.笔者在之前也是认为OOP是面向对象的主要部分,那么和我持有一样想法的,下面先要纠正这一想法,真正了解面向对象. 一.初识面向对象 面向对象分为三部分,包括面向对象分析(OOA).面向对象设计(OOD).面向对象的程序设计(OOP). 1.1 OO编程(Object Oriented Analysis) 典型的OO编程过程,应先整理需求

JavaScript基础--面向对象三大特性(八):继承封装多态

一.构造函数基本用法:function 类名(参数列表){属性=参数值} 1 function Person(name,age){ 2 this.name = name; 3 this.age = age; 4 } 5 6 //创建Person对象的时候,可以直接给名字和年龄 7 var p1 = new Person('abc',80); 8 window.alert(p1.name); 9 var p2 = new Person('hello',9); 10 window.alert(p2.

javascript的面向对象详解

每次说到javascript到面向对象,总感觉自己心里懂,但是却不知道该怎么说,这就是似懂非懂到表现,于是乎,每次一说,就要到处去查找资料,零零碎碎到看了一些,感觉有懂了,但是过段时间,好像又不知道是怎么回事了,于是乎,又到处找资料,然道是我本来就缺对象?才不理解对象是啥,以至于现实中找找对象,javascript中也在找对象!哎,好尴尬啊!直到我看到了一个妹纸写到“不可不知的javascript面向对象”,我才明白面向对象是什么,这是不是说我要找到对象就是这个妹纸呢??,先记录一下备忘吧,下面

[天天向上中]JavaScript系列----面向对象的JavaScript(2)

http://www.midifan.com/moduleuser-index-431566.htmhttp://www.midifan.com/moduleuser-index-431711.htmhttp://www.midifan.com/moduleuser-index-431496.htmhttp://www.midifan.com/moduleuser-index-431703.htmhttp://www.midifan.com/moduleuser-index-431798.htm

Javascript的面向对象基础

今天学习了一些关于javascript面向对象的基础,之前在网上也陆续接触过一些,不过都感觉理解的不够透彻,所以今天做一个小结. 首先javascript的面向对象还要从何为对象说起,所谓对象可以看作是一个黑盒子,你并不清除它内部实现功能的原理,但是你只要了解它是如何使用的,并且能够用它自带的功能完成自己想要做的事情,基本上来说这就是面向对象的思想.其实面向对象的思想生活中随处可见,电视机,电冰箱,空调等等,都可以看作是对象,拿一般人来说,无需知道它们的工作原理,但只要按说明书去使用即可. 回归

JavaScript中面向对象那点事

鉴于自己在JavaScript这方面比较薄弱,所以就找了一本书恶补了一下(被称为犀利书的JavaScript权威指南).书的内容虽然多了点,但这也充分说明了js中的东西还是挺多的.虽然我们的定位不是前端,但最好还是了解一下js这个发展了将近20年但依然很火的技术. 两年前,写过一篇关于JavaScript闭包的博客,所以对闭包这个词印象很深,在看这书的时候,又看到了闭包,那么这次再看闭包,会有什么不同的理解呢? 大家都知道,在JavaScript中是没有类的概念的,更没有私有.公有的成员变量这样

轻松学习JavaScript十三:JavaScript基于面向对象之继承(包含面向对象继承机制)

一面相对象继承机制 今天算是什么都没干,尽在了解面向对象三大特性之一的继承了,过去的学习的C++和C#都是正统的面向对象语 言,学习的时候也没有怎么深入了解过,只是简单的学习最基础的继承.下午在看继承机制的时候,看到一个很经典 的继承机制实例.这个实例使用UML很好的解释了继承机制. 说明继承机制最简单的方式是,利用一个经典的例子就是几何形状.实际上,几何形状只有两种,即椭圆形(是圆 形的)和多边形(具有一定数量的边).圆是椭圆的一种,它只有一个焦点.三角形.矩形和五边形都是多边形的一种, 具有

(转载)JavaScript中面向对象那点事

鉴于自己在JavaScript这方面比较薄弱,所以就找了一本书恶补了一下(被称为犀利书的JavaScript权威指南).书的内容虽然多了点,但这也充分说明了js中的东西还是挺多的.虽然我们的定位不是前端,但最好还是了解一下js这个发展了将近20年但依然很火的技术. 两年前,写过一篇关于JavaScript闭包的博客,所以对闭包这个词印象很深,在看这书的时候,又看到了闭包,那么这次再看闭包,会有什么不同的理解呢? 大家都知道,在JavaScript中是没有类的概念的,更没有私有.公有的成员变量这样

javascript 的面向对象特性参考

最近在看用javascript+css实现rich client.javascript 也是一个蛮有意思的语言.特别是其面向对象的实现和其他“标准”的OO launguage有很大的不同.但是,都是动态语言,我还是觉得它比起python语法和库都差得太远.可是没有explorer支持python开发 啊...:( 这是我学习javascript中面向对象特性的一点总结.希望对具有其他语言的面向对象设计经验的朋友理解javascript的OO有所帮助.我具有c++,java和python的面向对象