1、函数的参数
1-1:函数的形参个数
测试1:
function test(a,b){
alert(test.length);
}
test(10,20);
结果:输出2
测试2:
function test(a,b){
alert(arguments.callee.length);
}
test(10,20,30);
结果:输出的形参个数2个
1-2:函数的实参个数,利用arguments对象
测试1
function test(a,b){
alert(arguments.length);
}
test(10,20,30);
结果:输出实际参数个数3
1-3:函数实际参数的值
测试1:
function test(a,b){
console.log(arguments[0],arguments[1],arguments[2]);
}
test(10,20,30);
结果:依次输出实际参数的值:10,20,30
1-4:递归实现阶乘函数
测试1:
function fact(num){
if(num<=1){
return 1;
}else{
return num*fact(num-1);
}
}
alert(fact(5));
结果:输出120
测试2:
function fact(num){
if(num<=1){
return 1;
}else{
return num*fact(num-1);
}
}
var F = fact();
fact = null;
console.log(F(5));
结果:报错Uncaught RangeError: Maximum call stack size exceeded
测试3:
function fact(num){
if(num<=1){
return 1;
}else{
return num*arguments.callee(num-1);
}
}
var F = fact;
fact = null;
console.log(F(5));
结果:输出120,callee函数是arguments对象的秘密属性,它能返回arguments对象所属的函数的引用,这相当于在自己的内部调用自己。
2、this对象
this对象是在运行时基于函数的执行环境绑定的。
在全局函数中,this等于window,而当函数被作为某个对象的方法调用时,this等于那个对象,也就是说this关键字总是指代调用者
测试1
var k = 10;
function test(){
this.k = 20;
}
alert(test.k);
结果:输出undefined
测试2:
var k = 10;
function test(){
this.k = 20;
}
alert(k);
结果:输出10
测试3:
var k = 10;
function test(){
this.k = 20;
}
window.test();
alert(k);
结果:输出20
测试4:
var k = 10;
function test(){
this.k = 20;
}
test();
alert(k);
结果:输出20
3、call和apply
每一个函数都包含两个非继承而来的方法:call、apply。这俩个方法的用途都是在特定的作用域中调用函数,实际上等于设置函数体内this对象的值。
call、apply的用途之一就是传递参数,但事实上,它们真正强大的地方式能够扩充函数赖以运行的作用域。
使用call()、aplly()来扩充作用域的最大好处就是对象不需要与方法有任何耦合关系。
1-1:绑定一些函数,传递参数 调用
测试1:
function sum(x,y){
return x+y;
}
function call1(num1,num2){
return sum.call(this,num1,num2);
}
alert(call1(10,20));
结果:输出30
测试2:
function sum(x,y){
return x+y;
}
function apply1(num1,num2){
return sum.apply(this,[num1,num2]);
}
alert(apply1(20,30));
结果:输出50
1-2:扩充作用域
测试1:
window.color = "red";
var obj1 = {color:"blue"};
var obj2 = {color:"yellow"};
function showColor(){
alert(this.color);
}
showColor(window);
结果:输出red
测试2:
window.color = "red";
var obj1 = {color:"blue"};
var obj2 = {color:"yellow"};
function showColor(){
alert(this.color);
}
showColor.call(window);
结果:输出red
测试3:
window.color = "red";
var obj1 = {color:"blue"};
var obj2 = {color:"yellow"};
function showColor(){
alert(this.color);
}
showColor.call(obj1);
结果:输出blue
测试4:
window.color = "red";
var obj1 = {color:"blue"};
var obj2 = {color:"yellow"};
function showColor(){
alert(this.color);
}
showColor.call(obj2);
结果:输出yellow
3、call方法的简单模拟与实现
测试1:
//function 方法
function test1(a,b){
return a+b;
}
// 自定义的对象
function Obj(x,y){
return x*y;
}
var o = new Obj(10,20);
alert(test1.call(o,x,y));
结果:报错Uncaught ReferenceError: x is not defined at 1.html:19,因为参数x,y并没有在Obj对象里面进行赋值
测试2:
function test1(a,b){
return a+b;
}
function Obj(x,y){
return x*y;
}
var o = new Obj(10,20);
alert(test1.call(o,o.x,o.y));
结果:输出NaN
测试3:
function test1(a,b){
return a+b;
}
function Obj(x,y){
this.x = x;
this.y = y;
return x*y;
}
var o = new Obj(10,20);
alert(test1.call(o,o.x,o.y));
结果:输出30
测试4:
function test1(a,b){
return a+b;
}
function Obj(x,y){
this.x = x;
this.y = y;
return x*y;
}
var o = new Obj(10,20);
o.method = test1;
alert(o.method(o.x,o.y));
delete o.method;
结果:输出30,和上面test1.call(o,o.x,o.y)等价