引用传参--面向对象的魅力

引用传参--面向对象的魅力

 

         面向对象开发作为一种主流的软件开发方式,极大地改变了我们开发软件的方式。其遵从人类认识世界的普遍规矩,将现实中纷繁复杂的事物抽象为业务实体类,这就是由具体到抽象的认知过程;其积极响应软件工程的需求,其使我们开发的软件具有灵活性、扩展性、维护性的能力,极大地促进了软件开发的发展。

         那么传递参数的时候,面向对象技术能给我们带来什么好处呢? 今天就以昨天碰到的问题作为引子,我们来简单的了解一下面向对象传参的魅力!

         在web开发中,我们经常需要从父页面传递参数到子页面中,具体的代码如下,

        


        function showModelDialog(xml) {
            var url = "child.htm?parameter=123456";
            var parameter = "123456";
            window.formXml = xml;
            window.showModalDialog(url, parameter);
        }

代码中,我们使用showModelDialog来打开一个模式对话框,这个时候我们往往会传递一些参数过去,一般情况我们会有两种方式实现

1.       url传递参数

2.       通过showModelDialog的第二个参数传递

那么这两种方式有什么区别呢?

1.       前者传递的数据简单类型单一,只能作为字符串传递;

2.       前者传递的字符串不能包括特殊的字符,同时字符串的长度不能太长;

3.       基于浏览器安全的考虑,包含某些字符串的参数不能传递(比如跨站脚本攻击);

 

所以很多的时候,我们会更乐意使用第二种方式来传递参数,但是这种方式又有什么特点呢?又怎么能体现面向对象技术传递参数的魅力呢?先别急,还是先来简单的了解一下我遇到的问题吧,我们的产品在父页面中通过复杂的业务逻辑形成了一个xml格式的数据源,然后将这个数据源传递给子页面来展现。我是通过第二种方式实现的。本来一直运行相安无事,但是昨天事业部的客户反馈打开子页面的时候抛出异常;经检查配置的数据没有什么异常,唯一的差别就是配置形成的xml数据源字符串的长度比较大,那么会不会是由于参数传递有长度限制,截断了部分的字符串,导致子页面解析数据源的时候出错?想到这里,我就逐渐字符个数来测试,终于我测出来这个长度限制就是4096个字符,我们可以通过以下我写的例子测试

 

//测试类
        var PassParameterTester = {
            //新的页面地址
            url: "NewPage.htm"
            ,
            //获取字符个数为4096的参数
            getParameter4096: function () {
                return this.getParameter(4097);
            }
            ,
            //获取参数的个数为4097的参数
            getParameter4097: function () {
                return this.getParameter(4098);
            }
            ,

            getParameter: function (count) {
                return new Array(count).join("x");
            }
            ,
            passValueParameter4096: function () {
                this.passValueParameter(this.getParameter4096());
            }
            ,
            passValueParameter4097: function () {
                this.passValueParameter(this.getParameter4097());
            }
            ,
            //参数作为值类型进行传递
            passValueParameter: function (parameter) {
                this.showModelDialog(this.url, parameter.toString());
            }
            ,       
            showModelDialog: function (url, parameter) {
                window.showModalDialog(url, parameter);
            }
        };

 

我们调用PassParameterTester.passValueParameter4097(),通过以下图片中显示的长度,我们可以看到字符串被截断了。

 

 

图 1. 过长字符串经历传递被截断后的长度

 

         那么现在我们该怎么做了,我们既不能限制客户配置产生的字符串的长度,同时也不能从数据库、或者文件中获取,除了形成数据源需要复杂的业务逻辑,同时子页面也需要反复的保存客户的临时数据。那我是最终怎么实现的呢?我们知道js对象可以在创建后动态的添加成员,所以我将xml字符串赋值给window对象的formXml属性,然后在子页面中通过传递过去的window来获取。

         后来静下来仔细想想,难道我们只能使用window对象吗?window是引用类型变量,那是不是任何引用变量都可以呢?我们可以通过以下的例子进行验证

        

 

//测试类
        var PassParameterTester = {
            //新的页面地址
            url: "NewPage.htm"
            ,
            //获取字符个数为4096的参数
            getParameter4096: function () {
                return this.getParameter(4097);
            }
            ,
            //获取参数的个数为4097的参数
            getParameter4097: function () {
                return this.getParameter(4098);
            }
            ,

            getParameter: function (count) {
                return new Array(count).join("x");
            }
            ,
           
            passReferenceParameter4096: function () {
                this.passReferenceParameter(this.getParameter4096());
            }
            ,
            passReferenceParameter4097: function () {
                this.passReferenceParameter(this.getParameter4097());
            }
            ,
            //以引用类型进行传递
            passReferenceParameter: function (parameter) {
                this.showModelDialog(this.url, { arg: parameter })
            }
            ,
            showModelDialog: function (url, parameter) {
                window.showModalDialog(url, parameter);
            }
        };

 

 

图 2. 大于4096的字符串成功传递了

 

         从图中我们看到,参数已经被正确的传递过去了!那么这又是为什么呢?这个大于4096的字符串怎么传递过去的呢?难道这就是地址传参吗,我们知道js里是没有地址传参这回事的,其参数都是传值的,就是java和C#一般的情况下参数也是传值的,但是我们在C#里可以通过in、out、ref来实现地址传参的。

         我们都知道传值传参的时候,我们在函数中改变了参数的值,其对应的变量的值并不改变,值类型传参就是将变量保存的内容复制到函数的形参中,他们是两个不同的变量,值不过保存的内容相同不了,具体如图3

 

 

图 3. 值类型传参

 

         引用变量保存的是一个地址,这个地址里保存的是变量的具体值,而引用类型作为参数的时候,是将变量保存的地址值赋值到参数变量里,这样他们都指向了同一个内容,这样我们改变参数的成员的话,那么相应的变量的成员也会改变。

 

图 4. 引用类型传值传参

 

         如果我们在函数中为参数重新赋值,那么对应的变量是不是也改变呢?答案是显然的,传值传参是不可能改变外部变量的。

 

 

图 5. 引用类型内部赋值

 

         同样是传值传参,引用类型和值类型传参的本质是一样的,都是将变量保存的东西直接复制给形参,其实这跟赋值操作是一样的。但是由于引用对象的地址是一个数字,所以传参的时候,不过引用类型的值具体是多么大的数据,我们都可以安全的传递。

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值