代码改变世界

小菜的前端编程散谈(6)

2015-09-18 18:07  周信达  阅读(212)  评论(0编辑  收藏  举报

接上篇,其实Javascript调试网上有教程的,这里贴一个菜鸟网教程里的:Firebug使用教程
还有一个小技巧,在Javascript里面设置一个关键字:debugger(一般单独放在一行),那么运行起来的时候,断点会自动在debugger的地方停下来,然后就可以进行调试了。这也是一个比较常用的调试技巧。
参数传值和引用类型
怎么解释参数传值呢?一般函数的参数传值分为按值传递与按引用(或者叫按指针)传递,正常情况下函数的参数都是按值传递,某些编程领域支持按参数传递参数(一般使用关键字ref、out或者取地址符号&等),Javascript貌似不支持按引用传递参数。OK我们先抛开参数传值不谈,我们先谈一下值类型(也叫基本类型)和引用类型的区别,因为Javascript其实是区分值类型和引用类型的,当然大部分的现代编程语言都支持,那么什么是引用类型什么是值类型呢?我在下面稍微阐述一下:

值类型,通常表示一个值,从现实抽象来说,表示一个无状态的数据,比如数字、声音、文本等,值类型的赋值一般是拷贝操作,比如:var a = 1; var b = a;第二句我们把a的值赋给a,其实是把a的值拷贝一份,然后b实际上存储的是a的值的拷贝1.虽然它们的值都是1,但是他们在内存中是存储在不同的地方。如果此时我们再加一句代码,b = 2;此时b的值变为2了,但是a的值还是1。值类型一般是不可变的。所以在按值传递的函数中,传递的参数,如果在内部改变了它的值,其实只是改变参数拷贝副本的值。比如写一个函数function double(a) { a = a*2; } 然后调用double(a),这实际上并不会改变a的值,因为函数内部的参数a实际上是外面变量a的一个拷贝副本(其实函数参数a改为b或c都行,它只是一个参数代号,和用来存储外面变量a的副本。)。
引用类型,引用类型通常表示一个对象,从现实抽象来说,表示一个有状态的东西,比如人、动物,对象一般是具有行为的,可以改变内部状态,所以引用类型其实也是可变的(注意这个可变)。在内存中,引用类型的赋值其实就是内存地址的拷贝操作,比如我在看中央5套,我打电话告诉你让你也看中央5套,这里中央5套表示内存地址,而打开电视以后,电视里放的体育节目就是内存中存放的真实值。所以,引用的赋值等于是多个变量都指向同一块内存。这里有个比较绕的概念,我举个例子,var x = new Person(); x.Name="bruce";x.Age=18; var y = x;看到没有,此时y和x指向同一个人(不是拷贝或副本),OK,此时 y.Age=19,此时y改变了人的年龄属性,这时调用 x.Age看看,x.Age也是19了(可以自己建一个Person类对象写代码试试,类或者叫对象都是引用类型)。但是这里要注意了,如果y重新赋值 y = new Person(); y.Name="andy";此时x的值会变成andy吗?不会,为什么呢?对象或者说引用类型的可变性是表示对象可以改变内部状态,但是对象不能改变它自己,上述y=new Person();其实等于是将y重新指向了一个新的对象。我举个例子,我和你坐在一个桌子上吃饭,我和你都指向桌子这个对象,你夹菜吃菜都会改变桌子内部数据的状态,我夹菜吃菜也一样,就是说我们两个同事可以改变一个对象的内部数据状态。但是,如果我注意了,虽然我夹菜的动作是可以改变状态并且对你可见。但是如果我换一个桌子吃饭呢?此时我和你就不再指向同一个对象了,理解了没有?
函数传值,理解了值类型(或者叫基本类型)和引用类型之后,再理解函数传值就比较简单了,如果是按值传参数,那么在函数内其实是参数的拷贝,如果参数是引用类型,那么拷贝的就是内存地址(电视机看中央5套的例子,中央5套就是内存地址,体育节目就是内存数据)。此时其实可以在参数内部改变内存地址指向的数据状态,但是不能改变存储内存地址的指针本身。比如 function ChangeAge(person) { person.Age=18;} ,假设person是引用类型,这里按值传递 内部可以改变person的内部状态属性。但是 function ChangePerson(person) {person = new Person();} 这个函数里面把person重新指向另一个地址,这只是改变了指针的指向,不会改变指针原来指向的内存数据的内容,要懂得区别。那什么情况下可以改变指针的指向呢?那就是按引用传递了,Javascript里面没有按引用传递参数,我这里暂时先不提

我这里描述得不一定好理解,尽量仔细读一下吧。网上有讲得比较细的一些文章,主要是配了一些图片,比较容易帮助理解,你自己去搜过来看一下吧,一定要注意引用类型和值类型的区别。

我把示例代码放到了附件中,你自己下载下来跑一下,感受一下区别

源码下载