關於JS函數部分的筆記

函數

函數對象

首先來理解一下什麼事對象: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個部分,分別是:函數

  • 保留字 function
  • 函數名 add
  • 參數 a、b
  • 語句 return a+b;

函數字面量能夠出如今任何容許出現的地方,也能夠定義在其餘函數中。一個內部函數除了能夠訪問本身的參數和變量,同時它也能自由地訪問它的父函數的變量和參數。經過函數字面量建立的函數對象包含一個鏈接到外部上下文的連接。這被稱爲閉包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調用模式。生命週期

  1. 方法調用模式

當一個函數被保存爲對象的一個屬性是,咱們稱之爲方法。當一個方法被調用時,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"
相關文章
相關標籤/搜索