jscallee(js callee caller)

http://www.itjxue.com  2023-01-24 15:27  来源:未知  点击次数: 

Js中caller和callee的区别

首先,每个函数都有一个arguments对象(即通常所说的参数对象,这个对象只在函数内部可用),它引用了传递给这个函数的参数。而callee是arguments对象的一个属性,引用的是arguments对象代表的参数所在的函数。假设有一个函数 function f(a,b,c),则arguments是对参数a,b,c的引用,arguments.callee是函数f(是参数a,b,c所在的函数)。

caller是什么呢?caller是函数的一个属性,引用了调用本函数的父函数,如果是顶层调用(即没有父函数),则返回null。假设有两个函数f1和f2,且在f1中调用了f2,则f2.caller就是f1。也就是说caller是对调用本函数的父函数的引用。

最后总结一下:

caller返回一个函数(父函数)的引用,这个函数调用了当前的函数;callee返回正在执行的函数本身的引用,而它是arguments对象的一个属性。

还有,使用caller时要注意:

1 这个属性只有当函数在执行时才有用,

2 如果函数是由顶层调用的,则caller返回null。

js严格模式为什么要禁用callee

早起版本的 JavaScript 没有具名函数表达式(named function expression),所以在函数表达式里么没有办法实现递归。

比如下面实现阶乘的函数:

function?factorial?(?n?)?{

????return?!(?n??1?)???1?:?factorial(?n?-?1?)?*?n;}[1,2,3,4,5].map(factorial);

如果写成函数表达式的话:

[1,2,3,4,5].map(?function(?n?)?{

????//?这里要怎样递归?

}?);

所以添加了 arguments.callee 来实现对执行函数本身的调用:

[1,2,3,4,5].map(?function(?n?)?{

????return?!(?n??1?)???1?:?arguments.callee(?n?-?1?)?*?n;

}?);

但是现在的JavaScript 支持了具名函数表达式:

[?1,?2,?3,?4,?5?].map(?function?factorial(?n?)?{

????return?!(?n??1?)???1?:?factorial(?n?-?1?)?*?n;

}?);

这样写有以下的好处:

可以像正常一样调用函数

不会在函数外面的作用域创建变量(IE8或者更早的浏览器还是会)

比起用 arguments 对象来说,性能更加优秀

同时,使用 arguments.callee 还会带来函数引用优化问题和尾递归优化的问题。

以上部分内容资料来自:

js中函数的内部方法和属性指的什么?call()方法是谁的?每个对象都有这个方法吗?

arguments对象:函数内部对象,传入函数中所有参数的集合,类数组对象

属性:callee 指针,指向拥有这个arguments对象的函数 作用:解耦

例子:迭代

function factorial(num) {

if(num=1){

return 1;

}else{

return ( num*arguments.callee(num-1));

}

}

console.log(factorial(4));//24

this对象:函数内部对象,引用的是函数执行的环境对象 在全局作用域执行函数时this为全局对象(window)

window.color='red';

var o={color:'blue',};

function sayColor(){alert(this.color);};

sayColor(); //red

o.sayColor=sayColor;

0.sayColor();//blue 看this引用的谁

caller属性:指向调用当前函数的函数 保存着调用当前函数的函数的引用

function a(){

b();

}

function b(){

alert(b.caller)

}

b();//输出a函数体

apply()和call(): 作用:修改函数this的指向(修改上下文),拓展函数的作用域,对象与方法解耦 区别:传参 apply(要修改的指向,参数数组/arguments对象)

call(要求改成的指向,arg1,arg2...)

例子:哑巴说话

function PersonWei() {

}

PersonWei.prototype={

country:'Wei',

sayCountry:function () {

console.log('I am form '+this.country);

},

}

var xuShu={

country:'Shu',

}

var caoCao=new PersonWei();

caoCao.sayCountry();// I am form Wei

caoCao.sayCountry.call(xuShu); //I am form Shu

不知道这样做合不合理,定义了一个表示魏国人的构造函数PersonWei(),它具有属性:country和方法sayCountry(),然后实例了一个caoCao(曹操),我们想要帮xuShu(徐庶)说出自己的国家:caoCao.sayCountry.call(xuShu);让caoCao的this指向变为xuShu(借尸还魂?脑洞大开,应该就是鬼上身,借用你的身体来实现他的行为),这时候this.conutry 中的this指向的就是xuShu对象了,因此结果是 I am form Shu

javascript关于arguments.callee??

属性arguments.callee引用当前正在运行的函数。它给未命名的函数提供了一种自我引用的方式。该属性只在函数体内被定义。

关于JavaScript中argument.caller的理解问题!谢谢!

首先要分清caller和callee,arguments.callee返回当前正在执行的函数,function.caller返回函数的调用体所在函数。

随便弄了个示例代码

function?parentCheck()?{

????check("");

????function?check()?{

????????subCheck();

????????function?subCheck()?{

????????????console.log(arguments.callee);

????????????console.log(subCheck.caller.caller)

????????}

????}

}

parentCheck();

? arguments.callee返回subCheck的函数体,subCheck.caller返回调用subCheck的函数,即check,而再往上一层,subCheck.caller.caller就是返回调用check的函数体,也就是parentCheck。那如果是继续往上一层呢?subCheck.caller.caller.caller?就会变成null。书里也有讲,arguments.caller在非严格模式下永远是undefined。我们就可以判断值是null还是undefined来区分arguments.caller和函数的caller。

JS的函数是可以无限嵌套的,就构成了一棵树,而function.caller就提供了一个访问父节点的方法,通过灵活应用function.caller,我们甚至可以用脚本画出整棵树,只要我们在任意地方成功插入一段JS代码,又或者是,像网站统计之类的第三方代码,我们就能窥视其他代码。

所以为了安全期间,严格模式禁止调用caller、callee、arguments变量,在浏览器中的报错为

Uncaught?TypeError:?'caller',?'callee',?and?'arguments'?properties?may?not?be?accessed?on?strict?mode?functions?or?the?arguments?objects?for?calls?to?them

个人敝见,无书可循,希望对您有帮助

js里怎样在执行调用函数时得到调用它的函数

script?type="text/javascript"

????function?getCallableName(callee){

????????var?regex?=?/function\s*(\w*)/i;

????????return?regex.exec(callee)[1];????????

????}

????

????function?show(callee){

????????//1直接获取

????????alert(callee.name);

????????//2.正则表达式

????????alert(getCallableName(callee));

????}

????

????function?main(){

????????show(arguments.callee);

????}

????

????window.onload?=?function(){

????????main();

????};

/script

用这个试试;

(责任编辑:IT教学网)

更多

相关思科认证文章

推荐思科认证文章