分享一道题
function Foo() { getName = function() { console.log(5); } return this; } Foo.getName = function() { console.log(4); } Foo.prototype.getName = function() { console.log(3); } var getName = function() { console.log(2); } function getName() { console.log(1); } new Foo.getName(); // 4 new Foo().getName(); // 3 new new Foo().getName(); // 3 Foo.getName(); // 4 getName(); // 5 Foo().getName(); // 5 getName(); // 5
来分析一下:
首先看下:
new Foo.getName();
值得注意的是这个new是无参的(new Foo)
是从右到左执行的,即new (Foo.getName) ();
即执行Foo构造函数中的getName
函数为4,才去new
new Foo().getName();
这个new是有参的
是从左到右执行的,即(new Foo()).getName) ();
调用Foo
函数的返回值this,此时this
指向window
然后调用getName
函数。
getName
函数外部存在同名函数和变量,结果是变量覆盖了函数声明;
函数声明优先级大于变量声明,即函数声明先声明,容易被同名的变量声明赋值给覆盖住;
此时Foo
函数的第一句 getName = function () { alert (5); }
,
把getName函数替换了,覆盖了上面getName = function () { alert (2);}
,将此变量的值赋值为 function(){alert(5)}
本身构造函数中没有getName
属性,去找其原型对象中的getName
,//3
new new Foo().getName();
这个new是有参的
是从左到右执行的,即new ((new Foo()).getName)();
再次把foo的函数覆盖了,同上
先初始化Foo
的实例化对象,然后将其原型上的getName
函数作为构造函数再次new
,//3
Foo.getName();
访问Foo
函数上存储的静态属性4
getName();
此时的内容已经被第2步覆盖//5
Foo().getName();
此时的内容已经被第2步覆盖//5
getName();
此时的内容已经被第2步覆盖//5
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了