做用域:javascript
做用域是針對變量而言的,好比定義了一個函數啊a1,a1裏面又定義一個子函數a2,此時就會有三個做用域 全局做用域--a1做用域--a2做用域java
當a2查找變量時會先從自身的做用域開始查找,找不到就向上一級做用域a1查找,直到全局做用域,這就造成了一個做用域鏈react
原型:設計模式
javascript中,一切皆對象,每一個對象都會會有一個_propo_屬性(瀏覽器自動建立),該屬性指向它的原型,當一個對象查詢一個屬性的時候,自身沒有就會根據_propo_向原型查找,直到object.prototype._propo_爲null,這樣就造成了一個原型鏈瀏覽器
prototype是什麼呢?閉包
咱們直到咱們能夠經過一個構造函數建立一個類,prototype的做用就是讓類的屬性能夠被繼承,因此只有構造函數纔有prototype這個屬性app
繼承:函數
javascript中的繼承是經過原型鏈來體現的。先看幾句代碼學習
以上代碼中,f1是Foo函數new出來的對象,f1.a是f1對象的基本屬性,f1.b是怎麼來的呢?——從Foo.prototype得來,由於f1.__proto__指向的是Foo.prototypethis
訪問一個對象的屬性時,先在基本屬性中查找,若是沒有,再沿着__proto__這條鏈向上找,這就是原型鏈
那麼咱們在實際應用中如何區分一個屬性究竟是基本的仍是從原型中找到的呢?你們可能都知道答案了——hasOwnProperty,特別是在for…in…循環中,必定要注意。
等等,不對! f1的這個hasOwnProperty方法是從哪裏來的? f1自己沒有,Foo.prototype中也沒有,哪兒來的?
好問題。
它是從Object.prototype中來的,請看圖:
對象的原型鏈是沿着__proto__這條線走的,所以在查找f1.hasOwnProperty屬性時,就會順着原型鏈一直查找到Object.prototype。
因爲全部的對象的原型鏈都會找到Object.prototype,所以全部的對象都會有Object.prototype的方法。這就是所謂的「繼承」。
固然這只是一個例子,你能夠自定義函數和對象來實現本身的繼承。
說一個函數的例子吧。
咱們都知道每一個函數都有call,apply方法,都有length,arguments,caller等屬性。爲何每一個函數都有?這確定是「繼承」的。函數由Function函數建立,所以繼承的Function.prototype中的方法。不信能夠請微軟的Visual Studio老師給咱們驗證一下:
看到了吧,有call、length等這些屬性。
那怎麼還有hasOwnProperty呢?——那是Function.prototype繼承自Object.prototype的方法。有疑問能夠看看上一節將instanceof時候那個大圖,看看Function.prototype.__proto__是否指向Object.prototype。
原型、原型鏈,你們都明白了嗎?
這是個很寬泛的問題,利用閉包和原型能幹什麼事情。我從你題中的應用場景,分析下用原型和用閉包實現的不一樣點。
案例1:
function Girl(name){
this.name=name
}
Girl.prototype.sayname=function(){console.log(this.name)}
var a = new Girl('Lucy');
var b = new Girl('Lily');
案例2:
var Girl=function(name){
var sayname=function(){
console.log(name)
}
return {
sayname:sayname
}
}
var a = Girl('Lucy');
var b = Girl('Lily');
案例1中,a,b的結構以下圖所示(一些無關的屬性沒有徹底畫出):
關於閉包,我在內網論壇寫過一篇文章,有童鞋轉載到csdn JS閉包 - JokerWILL ,有興趣能夠看下。
因此咱們要了解原型和閉包的特性,瞭解使用原型和閉包會產生怎樣不一樣的結果,根據咱們的需求來靈活的使用。題主這問題問得....
原型鏈是幹什麼用的,是共享屬性和方法,是能夠實現繼承的
閉包是對變量和方法的封裝,能夠延遲使用外部變量和方法
構造函數上的方法是每一個實例對象都有這個方法,彼此不一樣
原型鏈的方法是各個實例對象共享這個方法
首先明白概念是什麼,可以幹什麼用,再說什麼模式一類的東西,模式是大量實踐總結出來的通用作法,js高級程序設計,必定多看幾遍