面试分析一
function Foo() { getName = function () { alert (1); }; return this; } Foo.getName = function () { alert (2); }; Foo.prototype.getName = function () { alert (3); }; var getName = function () { alert (4); }; function getName() { alert (5); } //请写出以下输出结果: Foo.getName(); // 2 getName(); // 4 Foo().getName(); // 1 getName(); // 1 new Foo.getName(); // 2 new Foo().getName(); // 3 new new Foo().getName(); // 3
1、Foo上的静态属性getName。
2、调用全局的getName函数,变量以及函数声明提前,函数表达式的应用。
var getName = function () { alert (4); }; function getName() { alert (5); } getName();
解析如下:
var getName; function getName() { alert (5); } getName = function () { alert (4); }; getName(); //4
3、先调用Foo(),再调用Foo()返回值的getName()方法。
执行Foo(),第一条语句是赋值语句,前面没有var 声明,在当前函数作用域中查找getName变量,没有找到,就往上层(一层一层向上找)作用域中查找,找到了就直接赋值,没有找到就在全局作用域中创建一个getName的变量。此时,全局作用域中的getName()方法已经被修改。
返回this,this指向是由所在函数的调用方式决定,此处直接调用,所以this指向的是window。
4、window.getName(),getName()在第三步中已经被改变了
5、运算符的优先级(https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Operator_Precedence)
点运算符高于new运算符 new Foo.getName() === new (Foo.getName())
6、new Foo().getName() === (new Foo()).getName():new Foo() 返回的是实例本身,调用实例的getName方法。
7、new new Foo().getName() === new ((new Foo()).getName)()