先看以下代码:
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();
getName();
Foo().getName();
getName();
new Foo.getName();
new Foo().getName();
new new Foo().getName();
怎么样?是不是有点糊涂了。
首先要明确下面一些基本知识:
1、 this
的指向只取决于调用的方式,,函数定义里面的this
指向全局的window
;
new
的过程:新建对象,让this
指向它,返回this
。
普通的函数调用时得到的值是return
的返回值,new
得到值可能是this
也有可能是return
的值,这取决于return
后面数据的类型。
2、实例化对象访问一个属性的顺序,先看自身有没有这个属性,再看访问原型里的。
3、new
后面跟的是一个构造函数,则会创建一个对象。如果是一个构造函数的属性名称,那么没有任何作用。
new
只会和离他最近的()
结合
请看下面的一张图:
一开始Foo.getName()
为1
,第5行代码将它修改为2
,所以Foo.getName()
的输出为2
;
getName()
是全局调用,函数提升优先于变量提升,到了第7行代码getName()
被修改为4
,所以输出为4
;
Foo()
是函数调用,得到的是return
后面的值this
,this
指向window
,并且第2行代码将getName()
修改为1
,所以结果为1
同理,getName()
的输出也是为1
;
new Foo.getName()
new
没有任何作用,这里是方法调用,输出值为2
new Foo().getName()
new
和最近的一个()
结合,所以得到了一个实例化对象,实例化对象自身没有getName
这个属性,所以访问原型里面的getName
,为 3
new new Foo().getName()
最前面的new
没有任何意义,同上一个