一、写在前面
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
二、解析
2.1、Foo.getName()
首先执行的是Foo.getName()
,所以直接访问的是该函数上的方法,所以直接打印2.
getName
指向该方法时,拿到的是全局上的方法,这里我们存在两种设置到全局的方法,一个是通过2.2、var getName
赋值的方式,第二种是通过function getName
直接进行定义的方式。这里涉及到变量的提升问题
,function getName
会先被提升到最前面,紧接着当执行的时候var getName
才会对函数进行赋值,所以此时会进行覆盖。
2.3、Foo().getName()
首先先执行Foo()
,此时其中存在一个getName
的函数,因为没有对齐使用var
定义,所以最终会将其放到window
上面,此时又会存在覆盖。并且 return this;
中的this指的是 window
,所以此时打印结果为1
。
2.4、getName();
此时再打印getName();
,访问的任然是window
上面的getName
函数,所以打印的结果为1
。
2.5、new Foo.getName()
根据优先级可以将其看作为new (Foo.getName)()
,所以最终打印的是2
。
2.6、new Foo().getName()
根据优先级顺序将其转化为(new Foo()).getName()
,前面拿到的是实例化对象,这里访问的是实例化对象上的getName
,所以打印的结果为:3
。
2.7、new new Foo().getName()
根据优先级顺序将其转化为new ((new Foo()).getName)()
, new Foo()
拿到的结果为实例化对象
,所以最终打印结果为3
。
三、升级版
<script>
function Foo() {
this.getName = function () {
console.log(3);
return {
getName: getName
}
};
getName = function () {
console.log(1);
};
return this
}
Foo.getName = function () {
console.log(2);
};
Foo.prototype.getName = function () {
console.log(6);
};
var getName = function () {
console.log(4);
};
function getName() {
console.log(5);
}
Foo.getName(); //2
getName(); //4
console.log(Foo()) //window
Foo().getName(); //1
getName(); //1
new Foo.getName(); // 2
new Foo().getName();//3
new Foo().getName().getName(); //3 1
new new Foo().getName(); //3
</script>