<code>
function foo(){ //代碼1
getName=function(){
console.log(1);
};
return this;
};
foo.getName=function () { //代碼2
console.log(2);
};
foo.prototype.getName=function(){ //代碼3
console.log(3);
};
var getName=function(){ //代碼4
console.log(4);
};
function getName(){ //代碼5
console.log(5);
};
foo.getName(); //標號1,輸出2
getName(); //標號2,輸出4
foo().getName(); //標號3,輸出1
getName(); //標號4,輸出1
new foo.getName(); //標號5,輸出2
new foo().getName(); //標號6,輸出3
new new foo().getName(); //標號7,輸出3
</code>
剛看到這樣的東西的時候,我也迷惑了好久,細想也就是賦值、作用域、原型鏈的事。
首先代碼1中的<code>getName</code>,代碼4、5的<code>getName</code>的作用域都是<code>window</code>。
1.標號1處的<code>foo.getName()</code>;這個毫無疑問作用域直接找到,輸出2;
2.標號2處的<code>getName()</code>;主要在于代碼4和代碼5,在瀏覽器預解析上述代碼時,在解析到
代碼塊4上時,在內存中為<code>getName</code>申請了一塊空間,解析到代碼5的時候發現內存中已經有<code>getName</code>
了,所以就不在重新申請空間了。
在解釋執行階段,代碼4要給<code>getName</code>賦值,也即是<code>function(){console.log(4)}</code>;而代碼5只是一個函數申明,
所以最終<code>getName</code>的值是代碼4,所以輸出4
3.標號3處的<code>foo().getName()</code>,<code>foo()</code>執行完對<code>getName</code>重新賦了值,而且<code>foo()</code>的返回是<code>window</code>對象,所以<code>getName</code>輸出為1。
4.標號4處的<code>getName()</code>為什么會與標號2處的不同呢?因為標號3執行的時候,代碼1中對<code>getName</code>賦了
新值,所以輸出1
5.標號5處根據.與<code>new</code>的優先級關系,先執行<code>foo.getName()</code>,然后才執行<code>new</code>。
6.標號6處<code>new foo().getName()</code>,其實就是這樣<code>var f=new foo()</code>;<code>f.getName()</code>;f會先查找自身的<code>getName</code>方法,
沒有找到便會沿著原型鏈查找,在上述例子中,我們在<code>foo</code>的<code>prototype</code>上定義了<code>getName</code>,因此在原型鏈
上找到了<code>getName</code>方法。
7.標號7的這個沒弄懂,后邊補充。但是<code>new new foo()</code>會報錯,所以執行應該是<code>new (new foo().getName())</code>;如果是后邊這種就好理解了。參照6.就是把<code>foo.prototype.getName()</code>給<code>new</code>了一下
<blockquote>http://www.cnblogs.com/onepixel/p/5043523.html</blockquote>
<blockquote>https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Operator_Precedence</blockquote>
<blockquote>http://blog.csdn.net/hsd2012/article/details/52680758</blockquote>