js原型鏈
下面是一道js題目:
- function?C1(name){??
- ????if(name){??
- ????????this.name?=?name;??
- ????}??
- }??
- ??
- function?C2(name){??
- ????this.name?=?name;??
- }??
- ??
- function?C3(name){??
- ????this.name?=?name?||?"John";??
- }??
- ??
- C1.prototype.name?=?"Tom";??
- C2.prototype.name?=?"Tom";??
- C3.prototype.name?=?"John";??
- ??
- console.log(new?C1().name?+?","?+?new?C2().name?+?","?+?new?C3().name);??
要做出這道題,最重要是理解js中變量在原型鏈中查找的順序,
從內到外大致如下:
本地屬性 ---> ?prototype
變量查找順序:
能在本地屬性中找到的絕不去prototype中找
從內到外大致如下:
本地屬性 ---> ?prototype
變量查找順序:
能在本地屬性中找到的絕不去prototype中找
1).先來分析第一個
- new?C1().name??
- ??
- function?C1(name){??
- ????if(name){??
- ????????this.name?=?name;??
- ????}??
- }??
- ??
- C1.prototype.name?=?"Tom";??
由于這里沒有參數,默認被賦值成了undefined,所以到了if這里就進不去了,因此在C1本地
屬性中找不到name這個屬性,只能傻逼兮兮的往外找了,又因為C1.prototype.name = "Tom"的
存在,在prototype中找到了name屬性,所以最后打印出來的答案是"Tom"
2).接著來分析第二個
- new?C2().name??
- ??
- function?C2(name){??
- ????this.name?=?name;??
- }??
- ??
- C2.prototype.name?=?"Tom";??
由于這次還是沒有參數,同樣默認被賦值成了undefined,于是本地屬性name被賦值成了
undefined。于是在查找的時候一下子就查到了name的值為undefined,
因此C2.prototype.name = "Tom"并沒有什么卵用,最終答案為undefined
3).最后來分析第三個
- new?C3().name??
- ??
- function?C3(name){??
- ????this.name?=?name?||?"John";??
- }??
- ??
- C3.prototype.name?=?"John";??
同樣是沒有參數,undefined作為參數進來以后情況變成了這樣:
this.name = undefined || "John",然后結果很明顯了本地屬性name被賦值成"John"。
接著是從內往外查找,一下子就鎖定了本地屬性name,此時的值為"John"。
因此C3.prototype.name = "John"同樣沒有什么用
最后的結果:
這里還有道小菜:
- function?Foo()?{??
- ????this.say?=?function(){??
- ????????alert('本地方法');??
- ????}??
- }??
- Foo.prototype.say?=?function()?{??
- ????alert('prototype方法');??
- }??
- new?Foo().say();??
如果原型鏈上有相同的方法。那么會優先找本地方法,找到并執行,原型鏈上的方法就不執行了。
同樣的,屬性的查找也是這么個順序。
同樣的,屬性的查找也是這么個順序。