前端學習實踐筆記--JavaScript深刻【3】

    這章主要討論閉包和原型,以及面向對象和繼承。web

    閉包瀏覽器

    閉包充分利用了JS裏面做用域的概念,做用域的好處是內部函數能夠訪問定義它們的外部函數的參數和變量。使用閉包主要是爲了讀取函數內部的變量或者將函數內部的變量始終保持在內存中,而不讓JS垃圾回收機制回收,因此使用閉包會下降系統性能的,應該避免儘可能少用。閉包

    具體看下面三個例子:webstorm

var elems = document.getElementsByTagName('a');
for(var i = 0; i<elems.length; i++){
    elems[i].addEventListener('click', function(e){
        e.preventDefault();
        console.log('i am click' +i);
    }, false);
}
for(var i =0; i< elems.length;i++){
    elems[i].addEventListener('click', (function(i){
        return function(e) {
            e.preventDefault();
            console.log('i am click' + i);
        }
    }(i)), false);
}

for(var i = 0; i < elems.length; i++){
    (function(i){
        elems[i].addEventListener('click', function(e){
            console.log("i am click" + i);
        },false)
    }(i));
}

   第一個例子確定有問題,輸出的都是i am click11(總共有11個超連接),關鍵在於觸發監聽的時候,獲取到的i是當前循環以後的變量i,因此值是11.函數

   第二個例子和第三個例子都是實現閉包,第三個例子比較直觀易懂。這裏還涉及到一個當即執行的函數概念。性能

   當即執行函數學習

   有兩種寫法,推薦第一種,以下代碼所示,當即執行匿名函數,幫助封裝一些方法,而且不留下任何全局變量,保護命名空間的乾淨,另外在閉包中也常用。this

(function () {
    alert('hello world!');
}()); 

(function(){
    alert('hello world!');
})();

 還能夠像匿名函數中傳遞參數,以下代碼所示:固然若是你把一些插件的全局變量,例如JQuery,YUI,Global傳進去,那就能夠實如今他們插件的基礎上擴展,並且不用擔憂變量污染的問題。spa

(function(name){
    alert('hello world my name is '+name);
}('tonylp'));

 具體能夠參考文章JavaScript學習筆記(十四) 當即執行函數.net

      原型

      原型在不少場合都會用到,尤爲是面向對象方向。

      對於原型(prototype)記住它既是全部function類型的對象的一個屬性,這個屬性自己又是一個Object對象。(片面的說又是屬性又是對象)。因此咱們能夠給這個prototype對象添加任意的屬性和方法,既然prototype是對象的「原型」,那麼有該函數構造出來的對象應該都會具備這個「原型」的特性。也能夠這麼說,prototype提供了一羣類對象共享屬性和方法的機制。從這裏能夠看出可使用prototype在建立新對象的同時避免複製太多的東西佔用內存。我能夠只賦值新的變量,而使用公共的方法。還能夠經過原型繼承,實現原型鏈。

     以下代碼經過原型實現基礎的類,能夠看到SayHello這個公用方法。

function Person(name) {
    this.name = name;
}

Person.prototype.SayHello = function(){
    alert("Hello i am" +this.name);
}
var BillGates = new Person("Bill Gates");
var SteveJobs = new Person("Steve Jobs");
BillGates.SayHello();
SteveJobs.SayHello();
aler(BillGates.SayHello() === SteveJobs.SayHello()); // true

    接下來展現一段原型鏈代碼,object->person->employee,在SteveJobs調用SayHello的時候,首先遍歷employee對象,裏面沒有此方法,而後經過Person.call(this,name),進入Person對象,找到該方法,而後輸出,注意傳入參數this和name。 其實這也是基於原型的繼承,不是麼

function Person(name) {
    this.name = name;
}

Person.prototype.SayHello = function(){
    alert("Hello i am" +this.name);
}

function Employee(name, salary){
    Person.call(this,name);
    this.salary = salary;
}
Employee.prototype.showMeTheMoney = function(){
    alert(this.name + "$" + this.salary);
};
var BillGates = new Person("Bill Gates");
var SteveJobs = new Employee("Steve Jobs", 2345);
BillGates.SayHello();
SteveJobs.SayHello();
SteveJobs.showMeTheMoney();
aler(BillGates.SayHello() === SteveJobs.SayHello()); // true

    都到這裏了,必然能想到若是我在JS內置的對象上使用prototype,就能夠擴展內置對象的方法或者屬性了,是的,這條路是可行的。

    昨天說到一半的建立對象,接着繼續,利用原型來建立對象。

    基於原型建立對象

    方法1,只使用原型,可是這個方法很差,由於把全部對象的屬性也掛載到原型上了,太累贅,並且無法改。

var lev=function(){

    return "啊打";
};
function Parent(){


};
Parent.prototype.name="李小龍";
Parent.prototype.age="30";
Parent.prototype.lev=lev;

var  x =new  Parent();
alert(x.name);

  方法二,和函數結合,混合模型,這個比較好,屬性和方法分離

function Parent(){
    this.name="李小龍";
    this.age=32;

};
Parent.prototype.lev=function(){

    return this.name;
};;

var  x =new  Parent();

alert(x.lev());

方法三,動態加載,其實就是混合模型,多加了一些判斷,防止重複建立原型方法。

function Parent(){
    this.name="李小龍";
    this.age=32;
    ;
    if(typeof Parent._lev=="undefined"){


        Parent.prototype.lev=function(){

            return this.name;
        }
        Parent._lev=true;
    }

};

    說到原型,確定說到遍歷,而後說到hasOwnProperty()方法,用來判斷是不是函數自己的方法和屬性,而不是原型鏈上的方法和屬性,頗有用。看段簡單的代碼就能夠了。

Object.prototype.bar = 1;
   var foo={moo : 1}
   for (var i in foo) {
     if(foo.hasOwnProperty(i)) {
       alert(console.log(i))
     }
   }//此時只會輸出moo屬性

     JS中主要大的概念都已經說完了,還剩下一個this指針,經過this仍是講講繼承,還有AMD和CMD的一些簡單介紹,JS裏面的一些深坑,還有若是想繼續往上深刻的一些方向,在下一篇文章中結束吧。以後打算看看一些插件的源碼,主要的知識點概念就那些,其實這門語言也不難的,被各大瀏覽器廠商坑了,還有開發這門語言的人,留下了太多的深坑,總的來講仍是頗有意思的,徹底不一樣於C++,JAVA那套嚴謹的面向對象知識。

    話說大家用webstorm卡不卡,爲何我用着這麼卡呢。

    以上所有都屬我的思想總結,請你們轉載的時候附上原創連接: http://www.cnblogs.com/tonylp

相關文章
相關標籤/搜索