分享一道题
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