JavaScript函数(上)与java函数的区别
日期: 2019-01-05 分类: 个人收藏 355次阅读
下面从:1、函数的定义2、参数上的区别 3、变量作用域 3.2升权(与变量作用域有关) 等几个方面解释一下JavaScript函数与java函数的区别,并对JavaScript的函数进行详细说明。
-
函数的定义 区别
- java
public class a {
public static void main(String[] args) {
System.out.println(new a().sum(1,2)); //==>3
//静态方法只能调用静态方法,通过 new a().sum(1,2) 可以达到调用非静态方法的效果
}
public int sum(int a,int b) { // 访问权限 返回值类型 函数名(参数类型 参数名,...)
return a+b;
}
}
- JavaScript:
function sum(a,b){ //函数关键字 函数名(参数,参数)
var c = a + b;
return c;
}
undefined
sum(1,2);
3
从定义上看JS的函数定义比java简单,少了访问权限,参数类型等。这里说明JS和java是不相关的,采用两种语言比较是为了理解语言,区分语言,不是它们结构一样。由前边内容所知js只有var一种数据类型表达方式,即然只有一种就没必要在参数前边加参数类型了。而js的函数都是有返回值的,即使不写return 也会默认返回undefined。
可见,js与java的函数定义方法不一样,是因为它们使用环境不一样造成的。从根本上来说结构还是一样的,只是写法不一样。这时可以会好奇 c = a+b; a、b可能是数字也可能是字符串或者其他,那c的类型是不是就难以确定了,对的c的类型是根据a、b进行确定的,所以js的sum函数可能返回数字也可能返回字符串。为什么:+是一个重载运算符,在数字之间是数学意义上的+,在字符串是将字符串拼接。这也就导致了不同类型结果是不一样的,如sum(true,true)返回2,可见这时是把true转成整数1,在相加。举一反三:因为+是重载运算符,导致返回类型的不确定,如果把+换成-是不是只能返回number类型了呢,这是对的。因为当 - 时,会把字符转换成数字型再计算(数字型字符串转成数字,以非数字字符开头字符串转成NaN)。
2.参数上的区别
继续使用上边案例,在java中调用 sum()方法,必须在调用sum()方法时给的参数个数,与类型一样,否则是报错的(sum(1,1,2))。而js因为只有一种类型描述var,返回参数类型就不用管了(不知道这样是对是错),而js对参数个数也没有要求,即您任意给我参数,但我如何处理这些参数就不管您事了。不报错但结果可能和要求的不一样。下面看一下规则:
1、传少了:自动有参数设用undefined
如:sum(1);
NaN //可见 a=1,而b = 默认为undefined.相当于 1+undefined = NaN
2、传多了:自动把多余部分省略
如:sum(1,"2",3);
3 //可见3没有参加运算,相当于 1+“2”=1+2=3;
这时多与部分就不能调用了吗,能调用。得益与函数内部的arguments变量,该变量是内建变量,每个函数都能调用。
function sum(){ //演示arguments函数的用法
var a = 0;
for(var i = 0; i < arguments.length; i++)
a += arguments[i]; //arguments[n] 表示调用传过来的第n个参数
return a;
}
undefined
sum(1,2,3,4);
10 //这时我们就可以实现n个参数的相加,举一反三:java上也可以通过数组的方式进行多个参数的相加
sum(1,2,"e",4);
"3e4" // 1+2+"e"+4; 因为1+2是整数+整数,为3,等于3+“e"+4,而整数+字符串是把整数转字符串后拼接也就得到“3e4"
不要因为arguments[i]就把arguments看成数组,arguments只是一个类似数组的变量。
3、变量作用域
java上分为成员变量(在本类中类似全局变量)与局部变量:
static int c = 10; //在类中且不在函数中称为成员变量
public void sum() {
int d = 10;//在函数中称为局部变量
}
public static void main(String[] args) {
System.out.println(c);
System.out.println(d); //报错
//可见在一个函数中可以访问成员变量,而不能直接访问 一个函数中的局部变量
}
而JS中成员变量与局部变量的用法与其它语言一样,但最大的区别就是:js中并不是把代码块当做作用域,而是以函数作为作用域,函数内的是局部变量,函数外的是全局变量 。如java中while(int i)此时i是一个局部变量,作用域是这个循环,而js中只要这while不在函数中,此时i就是一个全局变量。
var global = 1; //全局变量
function js(){
var locat = 2; //在函数内部,所以是 局部变量
global++;
return global;
}
undefined
js();
2
js();
3
locat;
undefined //在函数外部,并没有找到undefined
注意:如果在函数内声明变量不加var,而该变量默认为全局变量,如把js()内的var locat = 2换成locat = 2;则locat为全局变量
3.2 升权
注意:java如果两个相同变量名的局部变量的作用域发生冲突是不允许的(本人认识),而两个相同变量名如果一个是成员变量,一个局部变量。局部变量的作用域会覆盖成员变量作用域。
int i = 0; //可见,java允许全局变量与局部变量的变量名相同
public static void main(String[] args) {
for(int i = 0; i < 2; i++) {
for(int i = 0; i < 2; i++) {
//报错,因为两个i既都是局部变量,作用域还冲突。java不允许
System.out.println(i);
}
}
for(int i = 0; i< 2; i++) {
//不报错,虽然在这个方法中有三个i,但作用域是不冲突的。而且它会覆盖全局
//变量i的作用域
System.out.println(i);
}
}
而js允许下面的写法(java不允许)
for(var i = 0; i<2; i++){
for(var i = 0; i<3; i++){ //这个i会覆盖上面的i
alert(i);
}
}
上面简单说了java会作用域的规定与js(c,c++也允许js的写法)的区别。下面说js独有的升权:
var a = 123;
undefined
function f(){
alert(a);
var a = 1;
alert(a);
}
上面代码,如果以java的思维,弹出警告分别为 123 1这对java来说是对的,但js却显示为 undefined 1。因为:
js中函数内被声明的所有变量都会被移动(或者是提升)到函数最开始的地方。注意,被提升的只有变量的声明。
也就是说上述代码等价于:
var a = 123;
undefined
function f(){
var a; //此时局部变量a,已经覆盖了全局变量a
alert(a);
a = 1;
alert(a);
}
现在看:第一个alert,因为a还没有赋值,默认就是undefined.第二个alert因为a已经赋值1。所以js显示undefined 1也是对的。
作用域链
作用域链指的就是变量的作用域,js中变量的作用域是以函数来划分的,在函数内是局部变量,在函数外是全局变量。
var global = 1;
undefined
function outer(){
var outer_local = 2;
function inner(){ //它做为一个函数的子函数,可以访问父函数的变量,父函数无法访问它的变量
var inner_local = 3;
return inner_local + outer_local + global;
}
return inner();
}
undefined
outer();
6
突破作用域链
上面说了作用链,全局访问不了局部变量,就是子能访问父,父不能访问子。突破作用链解决父访问子的问题
方法1:通过返回一个函数突破
var F = function(){
var b = "local variable";
var N = function(){
return b;
};
return N;
};
undefined
var c = F();
undefined
c();
"local variable"
首先在全局是访问不了局部变量b的,而N函数作为F函数的一个子函数是可以访问b,此时把N函数返回在全局变量,在全局下就可以通过返回的N函数访问局部变量b
方法2:通过在函数内定义一个全局变量(不加var)突破
var F = function(){
var b = "local variable";
var N = function(){
return b;
};
inner = N;
};
undefined
inner();
"local variable"
虽然inner是一个全局变量,但是它定义在函数内,所以它可以访问变量b
3、循环中闭包常见错误
function F(){
var arr = [],i;
for(i = 0; i < 3; i++){
arr[i] = function(){
return i;
};
}
return arr;
}
undefined
var arr = F();
undefined
arr[0]();
3
可见输出错误,这是因为arr[0]存放的是 function(){ return i; }; 而i在for执行完成后i变成了3。可以通过即时函数解决
function F(){
var arr = [],i;
for(i = 0; i < 3; i++){
arr[i] = (function(x){
return function(){ return x;};}(i));
}
return arr;
}
undefined
var arr = F();
undefined
arr[0]();
0
除特别声明,本站所有文章均为原创,如需转载请以超级链接形式注明出处:SmartCat's Blog
精华推荐