@greenfavo
2015-10-13T20:25:39.000000Z
字数 3387
阅读 612
js
有如下4中调用js函数的方式
1,作为函数
2,作为方法
3,作为构造函数
4,通过call()和apply()
1,当函数无明确返回值时,返回undefined
2,当函数有返回值时,返回值是什么就返回什么。
可以通过使用return语句实现将函数返回调用它的地方。
在使用return语句时,函数会停止执行,并返回指定的值。
函数通常会返回一个唯一的值,那么这个值也可能是另一个函数:
<script type="text/javascript">
//函数表达式
var box = function(){
var a=1;
return function(){
alert(a++)
}
alert(222);//永远不会执行
}
alert(box());//弹出"function(){alert(a++)}"
</script>
在这里,我们只需将返回值赋值给某个变量,然后就可以像使用一般的函数那样调用它了:
<script type="text/javascript">
var box = function(){
var a=1;
return function(){
alert(++a)
}
}
var newFunc = box();
newFunc();//2
</script>
如果想让返回的函数立即执行,可以使用box()()来执行这段代码。
js中所有函数的参数都是按值传递的,言下之意就是参数不会按引用传递。
PS:如果存在按引用传递的话,那么函数里的那个变量将会是全局变量,在外包业可以访问。
1,值类型:数值,boolean,null,undefined.
2,引用类型:对象,数组,函数。
引用类型指的是那些保存在堆内存中的对象,意思是,变量中保存的实际上只是一个指针,这个指针指向内存中的另一个位置,由该位置保存对象。
function(){
return ‘hi’; //单独的匿名函数是无法运行的,就算能运行也无法调用,因为没有名字
}
在js中任何匿名函数都是属于window对象。在定义匿名函数时候它会返回自己的内存地址,如果此时有个变量接收了这个内存地址,那么匿名函数就能在程序里使用了,因为匿名函数也是在全局执行环境构造时定义和赋值的,所以匿名函数的this指向window对象
(function(){
console.log(this===window);//true
})
//通过自我执行来执行匿名函数
<script type="text/javascript">
(function (){// (匿名函数)();第一圆括号放匿名函数,第二个圆括号执行
alert('Lee');
})();
</script>
//把匿名函数自我执行的返回值赋给变量
<script type="text/javascript">
var box = (function (){
alert('Lee');
})(); //弹出”Lee”;
alert(box);//弹出 undefined,如果写出alert(box()),那么只会弹出一个"Lee"
var box= (function () {
return 'hi';
})();
console.log(box);//hi
</script>
(function(age){
console.log(age);
})(18);//打印出18
var result=function(){
console.log(2);
}();
另一种语法也能得到同样的结果
var result=(function(){
console.log(2);
})();
将函数返回值分配给变量
var result=(function(){
return 2;
}());
全局函数与内置对象的属性或方法不是一个概念。全局函数它不属于任何一个内置对象。JS中包含以下7个全局函数,用于完成一些常用的功能:
escape();unescape();eval();isFinite();isNaN();parseFloat();parseInt();
functon ClassA(){};
ClassA.prototype={};
var a=new ClassA();
(function(){
//独立作用域
})();
所谓构造函数,就是通过这个函数生成一个新对象(object)
function Test(){
this.x=10;
}
var obj=new Test();
console.log(obj.x);//打印出10
可以使用new运算符结合像Object(),Date(),Function()这样的预定义的构造函数来创建对象并对其初始化。面向对象编程其强有力的特征是定义自定义构造函数以创建脚本中使用的自定义对象能力。创建了自定义的构造函数,这样就可以创建具有已定义属性的对象。
function Circle(px,py,radius){
this.x=px;//圆心的x坐标
this.y=py;//圆心的y坐标
this.r=radius;//半径
}
var acircle=new Circle(5,11,2);//调用构造器
使用构造函数的优点是,它可以根据参数来构造不同的对象。缺点是构造时每个实例对象都会生成重复调用对象的方法,造成了内存浪费。
function test(){
console.log("hello,world");
}
test();//居然输出hello,是不是很奇怪?
function test(){
console.log("hello");
}
test();//正常输出hello
很显然,第一个函数没有起作用,是不是很奇怪?因为被覆盖了。我们都知道JS解析引擎并不是一行行地执行代码,而是一段段地执行。在同一段程序中,定义式的函数语句会被优先执行,所以第一个定义的代码逻辑已经被第二个覆盖了,所以两次调用相同函数,只会执行第二个。声明定义被提前到顶部,赋值还是在实际的地方。
aapply()函数有两个参数:第一个参数是上下文,第二个参数是参数组成的数组。如果上下文是null,则使用全局对象代替。例如:
function.apply(this,[1,2,3]);
call()的第一个参数是上下文,后续是实例传入的参数序列,例如:
function.call(this,1,2,3);
这里的高阶函数可不是高数里的那个高阶函数,所谓高阶函数就是操作函数的函数,它接收一个或多个函数作为参数,并返回新函数。
当函数被调用时,会得到一个免费奉送的参数数组,那就是arguments数组。通过它,函数可以访问所有它被调用时传递给他的参数列表。这使得编写一个无需指定参数个数的函数成为可能。
var sum=function(){
var i,sum=0;
for(i=0;i<arguments.length;i++){
sum+=arguments[i];
}
return sum;
}
document.writeln(sum(1,2,3,456));
在ECMAScript中的参数在内部是用一个数组来表示,函数接收到的始终都是这个数组,而不关心数组中包含哪些参数。
实际上,arguments并不是一个真正的数组,它只是一个类数组的对象,它拥有length属性,但缺少所有数组的方法。另外,arguments对象的长度是由传入的参数个数决定的,而不是定义函数时的命名参数的个数决定的。
函数在定义或声明时,所有的参数都是形参,因此,我们可以根据实际情况来命名参数,函数也只有在被调用时才会传入实参。而每个函数在被调用时都会自动取得一个特殊变量:this。
函数的递归即一个函数在通过名字调用自身的情况下构成的:
通过使用argument.callee代替函数名:
//arguments.callee是一个指向正在执行的函数的指针
function factorial(num){
if(num<=1){
return 1;
}else{
return num*arguments.callee(num-1);
}
}