首先來理解一下什麼事對象:ECMA-262是這樣定義的「無序屬性的集合,其屬性能夠包含基本值、對象或者函數」,也就是說,對象是‘名/值’對的集合。數組
var person=new Object(); person.name="Jake"; person.age=18; person.sayName=function(){ alert(this.name); }
上面的例子建立了一個名爲person的對象,併爲它添加了兩個屬性:name、age和一個方法sayName。其中sayName用於顯示this.name(將被解析爲person.name)的值。閉包
咱們來看一段代碼:app
var add=function(a,b){ return a+b; }
函數字面量包含4個部分,分別是:函數
函數字面量能夠出如今任何容許出現的地方,也能夠定義在其餘函數中。一個內部函數除了能夠訪問本身的參數和變量,同時它也能自由地訪問它的父函數的變量和參數。經過函數字面量建立的函數對象包含一個鏈接到外部上下文的連接。這被稱爲閉包this
閉包這個概念是js這門語言中一個很是重要並且是很難掌握的知識點!
這裏只能淺顯地解釋一下什麼是閉包
咱們用一些代碼來解釋這個定義:prototype
function foo(){ var a=2; function bar(){ console.log(a); } return bar; } var baz=foo(); baz();//2 <--這就是閉包的效果
函數bar()的詞法做用域可以訪問foo()內部做用域,而後將bar()函數自己看成一個值類型進行傳遞。
在foo執行後,其返回值 bar()賦值給變量baz並調用baz(),實際上只是經過不一樣的標識符引用調用了內部的函數bar()。
在foo執行後,foo內部做用域不會被銷燬,由於一直都是bar()自己在使用,所喲foo內部做用域依然存在且可以一直存活,以供bar隨時進行引用。
bar依然對該做用域保持引用,而這個引用就叫做閉包。code
做用域的做用:控制着變量與參數的可見性以及生命週期。
定義在函數內部的參數和變量在函數外部是不可見的,而在一個函數內部任何位置定義的變量,在函數內部任何位置均可見。對象
var f00=function(){ var a=3,b=5; var bar=function(){ var b=7,c=11; //此時a=3,b=7,c=11; a+=b+c; //此時a=21,b=7,c=11; }; //此a=3,b=5,c沒有定義; bar(); //此時a=21,b=5; }
調用一個函數會暫停當前函數的執行,傳遞控制權和參數給新函數。js提供了四種調用模式:方法調用模式、函數調用模式、構造器調用模式以及apply調用模式。生命週期
當一個函數被保存爲對象的一個屬性是,咱們稱之爲方法。當一個方法被調用時,this被綁定到該對象,當對象與方法用「.」來鏈接時,那麼它就被看成一個方法來調用了。ip
var person={ name:"Jake", age:18, sayAge:function(age){ this.age=age; } }; person.sayAge(19); docunment.writeln(person.age);//19
2.函數調用模式
當一個函數並非一個對象的屬性時,那麼它就是被看成一個函數來調用的
var myobject={ } //添加一個新的方法 myObject.do=function(value){ this.value=value; var that=this; var helper=function(){ that.value=that.value+that.value; }; helper(); } myObject.do(3); console.log(myObject.value)//6
這裏面遇到一個問題,就是在helper函數內部的this指向的時這個函數本省,而不是全局對象。咱們找到一個很好的解決方法,那就是將this賦值給一個全新的變量that,那麼內部函數就能夠訪問到this,這樣就避免了內部函數裏面的this錯誤的綁定。
3 構造器調用模式
一個函數,若是建立的目的就是但願結合new前綴來調用,那就被稱爲構造函數
若是一個函數前面帶上new來調用,那麼就會建立一個鏈接到該函數的prototype(原型)成員的新對象,同時函數中的this會綁定到這個新對象中。
var Myobject=function(string){ this.status=string; } Myobject.prototype.get_status=function(){ return this.status; } //建立實例 var newObj=new Myobject("Hello !"); console.log(newObj.get_status()); //Hello !
這裏要特別注意:按照慣例,構造函數始終都應該以一個大寫字母開頭,而非構造函數則應該以一個小寫字母開頭。
4.Apply調用模式
Apply方法讓咱們構建一個參數組傳遞給調用函數。它容許咱們選擇this的值。Apply方法接受兩個參數,第一個要綁定給this的值,第二個就是參數數組。
var array=[3,4]; var sum=add.apply(null,array);//sum值爲 7
var statusObj={ status:'Hello' }; var status=Quo.prototype.get_status.apply(statusObj); //status值爲‘Hello’
function SpeciallArray(){ var values=new Array(); values.push.apply(values,arguments); values.toPipedString=function(){ return this.join("|"); } return values; } var color=new SpeciallArray("blue","yellow","red"); console.log(colo.toPipedString); //"blue|yellow|red"