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

来源:互联网 发布:编程儿童产业 编辑:程序博客网 时间:2024/05/17 08:41

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

 

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

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

         在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. 引用类型内部赋值

 

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

 

 

原创粉丝点击