gpt4 book ai didi

javascript - 获取函数名称,如 Chrome 控制台中打印的那样

转载 作者:行者123 更新时间:2023-11-29 10:45:05 26 4
gpt4 key购买 nike

考虑这段代码:

var o = {};
o.f = function(){};
new o.f;

Chrome 将 o.f {} 打印到控制台。你知道这个 o.f 部分是如何调用的吗?更重要的是,有什么办法可以不使用控制台就得到这个结果吗?我想从函数本身中提取方法的名称,也就是说,没有任何附加信息。

我已经知道在这种情况下如何获取名称:

function f(){}
f+'' // "function f(){}"

但在上述情况下它的行为方式不同。


以下内容大部分复制自comments .

我想知道是否有一个“技术”词来谈论这个 o.f 模式,例如“命名空间”、“标识符”或“函数路径”。然后,我想知道是否有办法从网页中加载的脚本中检索此信息。以下问题可能会帮助您理解我的目标,第一个代码块之后的段落非常接近我的想法:Does Chrome retain each object's constructor? .

也许我应该提到我最初的目标是在运行时生成文档:/在这种情况下,反射 API 之类的东西会有所帮助。更准确地说,我正在寻找一种方法将方法的名称包含到函数的反编译形式中。看:

function Class(){}
Class.prototype.method = function(){};

Class.prototype.method + '' 给出 function(){}。我想注入(inject)方法的名称以获得此结果:function method(){}

问题是我没有关于我当前正在序列化哪个函数的任何信息,因为该操作是在用户单击链接时发生的。我知道我可以轻松地将名称存储在某处,例如将数据绑定(bind)到 anchor 元素,这对我来说很明显,我只是想知道是否有一种方法可以像 Chrome 一样检索这些数据。

最佳答案

好吧,就所有这些构造的命名而言,这似乎是一个足够简单的问题:

o.f = function(){};

是一个普通语句,由更普通的表达式组成。 o.f只是访问对象属性的两种方式之一,通常称为点表示法。虽然我相信 JS,点 (.) 并没有真正被视为运算符,但今后我将把它称为运算符的成员。
接下来我们有著名的赋值运算符,它将右边的操作数赋给左边(对象 o 的成员,称为 f)。
右边的表达式(需要评估为奇异值)是一个函数定义,它不是单独的语句,而是用作表达式。鉴于这一事实,我们将函数的这种用法称为函数表达式

在这种特殊情况下,该函数没有名称,它是一个匿名函数。在内部,大多数(如果不是所有引擎的话)都会给它起一个名字,但这不是 JS 应该知道或关心的事情。就JS而言,这个函数没有名字,只能通过o.f访问。 .如果你像这样调用这个函数:o.f() , 它的上下文将是对象 o 的上下文,有效地使这个函数表现为一个方法。
所以基本上你的声明是这样的:“如果需要,分配并创建一个名为 of 的成员,一个匿名函数。” 函数本身没有名字。

考虑一下:

var o = {f: function(){console.log('I am a function');}};
var foobar = o.f;
foobar();//logs I am a function

所以说函数的名称 o.ff并不总是适用。其他变量或属性可以引用相同的函数。这是因为函数是第一类对象,它们可以从任何对象返回、传递和分配给任何对象。

那么,答案是使用这两种方法中的任何一种:

您可以通过添加名称来更改函数表达式,将其变成命名函数表达式:

f.o = function newName(){};

newName除了旧版本的 IE 之外,名称在函数范围之外不可用。这是 ECMA 规范要求的 see the details here .无论如何,现在我们可以检查一下:

var func = function func(){console.log(func);};
//same name:
func();//logs function func(){}
var foobar = func;
foobar();//logs function func(){}
func = 123;//<-- no longer function
foobar();//still function func(){}//func is still accessible
var hidden = (function()
{
return function named()
{
console.log(named);//access name
};
}());
hidden();//logs function named(){}
console.log(named);//undefined -> not visible outside the function itself

函数的名称被限制在它自己的范围内。

使用正则表达式,它有点笨拙,并且不会获取引用同一函数对象的两个变量/属性:

o = {f: function(){console.log('I am a function');}};
for (var pName in o)
{//probably add o.hasOwnProperty(pName) check to be safe
if (o[pName] instanceof Function)
{
console.log(o.f.toString().replace(
/^function\s*\(/,
'function o.'+pName+'(')
);
}
}

这将函数字符串化(给出 function (){/*body*/} )并替换 function (function <propertyName>( .如果该函数已有自己的名称,则不会替换该名称。

关于javascript - 获取函数名称,如 Chrome 控制台中打印的那样,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21014020/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com