function add(a,b){ alert(a+b);}function sub(a,b){ alert(a-b);}add.call(sub,3,1); 打印结果为4。调用add函数,但是调用对象(上下文环境)不是add对象,而是sub函数对象。注意:js中的函数其实是对象,函数名是对 Function 对象的引用。function Animal(){ this.name = "Animal"; this.showName = function(){ alert(this.name);} }function Cat(){ this.name = "Cat"; } var animal = new Animal(); var cat = new Cat(); animal.showName.call(cat,",");//输出结果为"Cat"animal.showName.apply(cat,[]);//输出结果为"Cat" call 的意思是把 animal 的方法放到cat上执行,上下文环境为cat,原来cat是没有showName() 方法,现在是把animal 的showName()方法放到 cat上来执行,而cat的this.name是Cat。所以this.name 应该是 Catfunction Animal(name){ this.name = name; this.showName = function(){ alert(this.name);} } function Cat(name){ Animal.call(this, name); } var cat = new Cat("Black Cat"); cat.showName(); Animal.call(this) 的意思就是调用Animal方法,但是使用 this对象代替Animal对象,上下文环境变成了this。new Cat("Black Cat")中使用Animal.call给当前的上下文环境设置了属性name和方法showName。function Class10(){this.showSub = function(a,b){ alert(a-b); }}function Class11(){this.showAdd = function(a,b){ alert(a+b); }}function Class2(){Class10.call(this);Class11.call(this);} 备注:js的继承还有其他方法,例如使用原型链,这个不属于本文的范畴,只是在此说明call 的用法。说了call ,当然还有 apply,这两个方法基本上是一个意思,区别在于 call 的第二个参数可以是任意类型,而apply的第二个参数必须是数组或arguments。function format(string) {var args = arguments;var pattern = new RegExp("%([1-" + arguments.length + "])", "g");return String(string).replace(pattern, function(match, index,position,all) { console.log(match + "&" + index + "&" + position + "&" + all);return args[index]; }); }; 掉用format("And the %1 want to know whose %2 you %3", "papers", "shirt", "wear");结果为"And the papers want to know whose shirt you wear";控制台打印为var args = Array.prototype.slice.call(arguments);那么现在这个变量args就含有一个含有函数所有参数的标准javascript数组对象。
function makeFunc() { var args = Array.prototype.slice.call(arguments); var func = args.shift(); return function() { return func.apply(null, args.concat(Array.prototype.slice.call(arguments))); }; } 该方法会将第一个参数取出来,然后返回一个curry化函数,该curry化函数的参数(第二个arguments)将和makeFunc的从第二个参数开始的参数组合成新数组。并返回makeFunc第一个参数的apply调用var majorTom = makeFunc(format, "This is Major Tom to ground control. I"m %1.");majorTom("stepping through the door");结果为:"This is Major Tom to ground control. I"m stepping through the door."
//用于验证参数function calleeLengthDemo(arg1, arg2) {if (arguments.length==arguments.callee.length) {window.alert("验证形参和实参长度正确!");return;} else {alert("实参长度:" +arguments.length);alert("形参长度: " +arguments.callee.length);}}//递归计算var sum = function(n){if (n <= 0) return 1;else return n +arguments.callee(n - 1)}//比较一般的递归函数:var sum = function(n){if (1==n) return 1;else return n + sum (n-1);} 调用时:alert(sum(100));其中函数内部包含了对sum自身的引用,函数名仅仅是一个变量名,在函数内部调用sum即相当于调用一个全局变量,不能很好的体现出是调用自身,这时使用callee会是一个比较好的方法。// caller demo {function callerDemo() {if (callerDemo.caller) {var a= callerDemo.caller.toString();alert(a);} else {alert("this is a top function");}}function handleCaller() {callerDemo();}handleCaller(); 执行结果:
c.undefined和null
--------------------------------------------------------------------------------
大多数计算机语言,有且仅有一个表示"无"的值,比如,C语言的NULL,Java语言的null,Python语言的none,Ruby语言的nil。有点奇怪的是,JavaScript语言居然有两个表示"无"的值:undefined和null。这是为什么?
相似性
在JavaScript中,将一个变量赋值为undefined或null,老实说,几乎没区别。
代码如下:
var a = undefined;var a = null;上面代码中,a变量分别被赋值为undefined和null,这两种写法几乎等价。
if (!undefined) console.log("undefined is false");// undefined is falseif (!null) console.log("null is false");// null is falseundefined == null// true上面代码说明,两者的行为是何等相似!但是我们去查看undefined和null的各自的类型却发现类型是不同的。js基础类型中没有null类型
typeof null;//"object"typeof undefined;//"undefined"既然undefined和null的含义与用法都差不多,为什么要同时设置两个这样的值,这不是无端增加JavaScript的复杂度,令初学者困扰吗?Google公司开发的JavaScript语言的替代品Dart语言,就明确规定只有null,没有undefined!
var i;i // undefinedfunction f(x){console.log(x)}f() // undefinedvar o = new Object();o.p // undefinedvar x = f();x // undefined 以上所述是小编给大家介绍的JS中call/apply、arguments、undefined/null方法详解,希望对大家有所帮助。