【JavaScript从入门到精通】第八课

来源:转载

第八课 深入javascript

这一课开始我们要讲一些更加深入的JS内容,掌握了这些内容,大家就有机会去做一些比较高级的JS效果了。


函数的返回值

说到函数的 返回值 ,它与我们前面提到过的函数传参正好相反。函数传参是把内容通过参数传递到函数内,而函数返回值的作用是将函数的一些结果传到外面。下面是一个最简单的函数传参例子。


function show(){
return 12;
}
var a=show();
alert(a);

结果如下:



12就是这个函数的返回值。函数的返回值返回到的地方就是调用函数的地方,本例中show的返回值返回到了变量a中,因此变量a的值变为了12。当然这个例子我们还可以直接这么写:alert(show());。


return不仅可以返回数字,还可以返回字符串,变量,算式等。通过使用函数传参和函数返回值,我们可以做一些稍微复杂的函数功能:


function show(a,b){
return a+b;
}
alert(show(3,5));

结果如下:



一般来说,函数只能有一个返回值。不过我们可以通过JSON等办法使函数返回多个值,具体方法我们以后再讲。


当然,函数可以有返回值,也可以没有返回值,我们前面编写的大部分函数都是没有返回值的。如果我们采用以下写法:


function show(a,b){
return;
}

也就是说,return空值,它和不写return在结果上是一样的,它们都会返回undefined。


我们曾经建议过,一个变量最好只存储一种类型的值。对于返回值来说也是同样的,我们建议,一个函数的返回值最好只返回一种类型的值。


函数传参 2

这里我们对函数传参进行更深入的讲解。在上面的函数返回值讲解中,我们写了一个最简单的求和函数,这个函数的功能是将2个数字相加并返回。如果我想进行三个数字或多个数字相加,这个函数就不能满足我们的要求了,需要对函数进行修改。那么,如果我们函数的参数是不固定的,我们应该怎么办呢?这个时候,我们需要用到arguments。


我们一般称使用arguments为可变参或不定参,采用arguments的函数其参数个数是可变的。arguments本质上是一个数组,数组内存储的内容就是我们传入的参数。我们可以通过下面一个例子来理解arguments:


function sum(){
alert(arguments.length);
alert(arguments[0]);
}
sum(12,6,8);

输出结果如下:



这里输出了参数的个数(3个)和第一个参数12。其实,arguments其实就是由参数组成的数组,具有数组的所有属性和功能。通过arguments数组,我们可以很轻松地解决不定参数求和的问题:


function sum()
{
var result=0;
for(var i=0;i<arguments.length;i++)
{
result+=arguments[i];
}
return result;
}
alert(sum(12,6,8,6,8));

结果如下:



我们再来看一个CSS函数的例子。假设我们存在这个一个css函数,若它的形式为:css(oDiv,样式)的时候,其作用为获取样式值,若它的形式为:css(oDiv,样式,样式值)的时候,其作用为设置样式。根据参数个数的不同,其函数功能也不一样。聪明的同学应该可以想到它是如何实现的:通过if判断arguments的长度,然后分别编写不同长度下的函数功能。


<html>
<head>
<meta charset="utf-8">
<title>无标题文档</title>
<script>
function css()
{
if(arguments.length==2)
//获取
{
return arguments[0].style[arguments[1]];
}
else
{
arguments[0].style[arguments[1]]=arguments[2];
}
}
window.onload=function ()
{
var oDiv=document.getElementById('div1');
alert(css(oDiv, 'width'));
};
</script>
</head>
<body>
<div id="div1" style="width:200px; height:200px; background:red;">
</div>
</body>
</html>

可以看到,如果总是使用arguement[i]的方式表示变量会使得程序的可读性非常差。实际上,我们依旧可以对不定参函数的参数进行命名,从而提高代码的可读性。可以将上面代码的JS部分进行如下修改:


function css(obj, name, value)
{
if(arguments.length==2)
{
return obj.style[name];
}
else
{
obj.style[name]=value;
}
}
window.onload=function ()
{
var oDiv=document.getElementById('div1');
alert(css(oDiv, 'width'));
};
非行间样式的获取

我们学过,当我们的样式写在行间的时候,JS可以通过style获取。然而,style也只能获取或操作行间样式,当我们需要获取的样式是非行间样式时,应该采用什么方法呢?


自然和style对应,JS还有一种用于获取非行间样式的方法:currentStyle。


<html>
<head>
<meta charset="utf-8">
<title>无标题文档</title>
<style>
#div1 {width:200px; height:200px; background:red;}
</style>
<script>
window.onload=function ()
{
var oDiv=document.getElementById('div1');
alert(oDiv.currentStyle.width);
};
</script>
</head>
<body>
<div id="div1">
</div>
</body>

currentStyle在IE浏览器和高版本chrome下可以正常运行,但不兼容于火狐等浏览器。为了兼容火狐浏览器,则必须用到以下方法:getComputedStyle()。字面意义来说,getComputedStyle()指的是获取计算后的样式,也就是元素最终的样式。getComputedStyle()有两个参数,第一个参数是你要获取的元素,第二个参数可以随便放置。将上面的代码改为:


alert(getComputedStyle( oDiv , false ) ) ;


这样就可以在火狐浏览器下兼容。然而,getComputedStyle在IE7下又不兼容了。这种情况下应该如何做到兼容所有浏览器呢?


如果我们在火狐浏览器下使用currentStyle,我们会发现它的返回值是undefined,而我们之前学过undefined的布尔值是false。而在IE浏览器下,currentStyle会返回一个object,其布尔值必然是true。因此,我们可以用过if语句来判断浏览器是否支持currentStyle。


if(oDiv.currentStyle)
{
//IE
alert(oDiv.currentStyle.width);
}
else
{
//火狐
alert(getComputedStyle(oDiv, false).width);
}

在JS里,大部分的兼容问题都是通过if语句解决的。


不过,大家可以思考一下,如果我每次获取样式的时候都进行这么一次判断,函数代码是否会显得太过复杂?这里我们采用封装的思想,将判断浏览器的代码封装到一个函数里,这样,以后使用的时候,只需要调用函数即可。完整代码如下:


<html>
<head>
<meta charset="utf-8">
<title>无标题文档</title>
<style>
#div1 {width:200px; height:200px; background:red;}
</style>
<script>
function getStyle(obj, name)
{
if(obj.currentStyle)
{
return obj.currentStyle[name];
}
else
{
return getComputedStyle(obj, false)[name];
}
}
window.onload=function ()
{
var oDiv=document.getElementById('div1');
alert(getStyle(oDiv, 'width'));
};
</script>
</head>
<body>
<div id="div1">
</div>
</body>
</html>

效果如下:



这样,这段代码基本上趋于完美了。但实际上,它还存在一点小问题。大家可以试试将width属性改为background,你会发现函数并不能获取div1的背景属性。这又是为什么呢?


在ccs,样式可以分为两类。一类叫 复合样式 ,这类样式是由很多小样式组合而成,例如background背景样式,其下有背景颜色,背景图片,背景位置等等。另一类我们把它叫做 单一样式 ,例如width,position等,已经是最基础的样式,没有组成部分。实际上,我们介绍的获取样式的方法都只能获取单一样式。因此,如果我们想获取div1的背景颜色,我们输入的参数不能是复合样式background,而应该是它下面的单一样式backgroundColor。


数组基础

我们已经讲过数组可以用[]的方法直接定义,实际上数组还有另一种定义方法:


vara=newArray(1,2,3);


他的效果与var a=[1,2,3]完全相同。


我们已经提到过数组的length属性,实际上数组的length属性不仅可以读取,还可以进行设置。例如:


var arr=[1,2,3,4,5,6];
arr.length=3;
alert(arr);

结果如下:



通过设置length等于0可以快速清空一个数组。


JS里,一个数组可以存不同类型的数据,但为了避免混乱,原则上我们一个数组只存一种类型的数据。


添加、删除元素

谈完了数组的定义,我们需要认识数组的各种方法。 第一组用于添加数组元素的方法是push(元素)和pop(),作用分别是从数组尾部添加或删除元素。


var arr=[1,2,3];
arr.push(4);
alert(arr);

var arr=[1,2,3];
arr.pop();
alert(arr);

结果分别如下:




和push与pop对应的,从数组头部添加或删除元素的方法是unshift(元素)和shift(),使用方法和push与pop相同,这里就不举例了。


但是,如果我们想从数组中间插入或删除元素,上面的几个方法就不再适用,而要用到splice方法。 splice的用于删除数组元素的形式为:数组名.splice(起点,长度)。其含义为删除从起点开始后与长度个数相同的元素。注意起点和下标一样从0开始。


var arr=[1,2,3,4,5,6];
arr.splice(2,3);
alert(arr);

结果为:



splice用于添加数组元素的形式为:数组名.splice(起点,长度,元素A,元素B...)。其含义为将元素A等元素添加到起点后。长度依然代表删除的元素个数,因此如果不想删除元素只添加元素,将长度设为0即可。


var arr=[1,2,3,4,5,6];
arr.splice(2,0,'a','b','c');
alert(arr);

结果为:



实际际上这个方法分为两步实现:首先将起点后的0个元素删除,再添加入a,b,c三个元素。


自然,如果删除的元素和插入的元素数量相同,splice就可以完成元素替换的功能。


var arr=[1,2,3,4,5,6];
arr.splice(2,2,'a','b');

结果为:



排序,转换


接下来我们来看几个有用的数组操作。


concat:用于数组的连接。


var a=[1,2,3];
var b=[4,5,6];
alert(b.concat(a));

结果为:



join:用于数组与其他元素的拼接。


var arr=[1,2,3,4];
alert(arr.join('-'));

结果为:



join的作用在于用自定义的字符将数组里的元素连接起来。


sort:用于数组的排序。


var arr=['float','width','alpha','zoom','left'];
arr.sort();
alert(arr);

结果为:


值得注意的是,数组里的数字也会被当做字符串处理,例如“12,8,99,19,112”会被排序成“112,12,19,8,99”,如果想让sort进行数值排列,需要用到一个函数参数:


var arr=[12, 8, 99, 19, 112];
arr.sort(function (n1, n2){
if(n1<n2)
{
return -1;//这个地方实际上只要是个负数就可以
}
else if(n1>n2)
{
return 1;//同理,这个地方实际上只要是个正数即可
}
else
{
return 0;
}
});
alert(arr);

这个时候,sort函数就可以发挥数值排序的功能了:



n1和n2参数是sort传入的,并通过返回不同的值告诉数组比较的数字孰大孰小。实际上,这个函数还可以直接简化为:


arr.sort(function (n1, n2){
return n1-n2;
});

因为数组判断数字大小的结果是根据返回值的正负性判断的,因此直接返回n1-n2也是可以的。


分享给朋友:
您可能感兴趣的文章:
随机阅读: