日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

javascript必知必会之prototype

發布時間:2025/6/15 javascript 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 javascript必知必会之prototype 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

摘要

本系列博文主要談一些在?javascript?使用中經常會混淆的高級應用,包括: prototype, closure, scope, this關鍵字. 對于一個需要提高自己javascript水平的程序員,這些都是必須要掌握的.

本節主要介紹prototype.

Contents

  • 摘要
  • 起由
  • prototype
  • 結論
  • 參考資料
  • 本文的rst源碼

起由

最近在做一個項目,里面大量地使用?javascript?作為頁面的動態生成腳本, 使用?json?與服務器進行通信. 在讀之前遺留的代碼時, 經常會弄不清楚, 作用域, this關鍵字在當前context下的指向等,于是便開始專門學習了 相關的知識,記錄下來與大家分享.

下面的內容中會有一些代碼,建議大家也去嘗試修改和理解,這樣更容易掌握. 點擊?這兒?下載所涉及到的源碼.

prototype

javascript?是一種?prototype based programming?的語言, 而與我們通常的?class based programming?有很大 的區別,我列舉重要的幾點如下:

  • 函數是first class object, 也就是說函數與對象具有相同的語言地位
  • 沒有類,只有對象
  • 函數也是一種對象,所謂的函數對象
  • 對象是按?引用?來傳遞的
  • 那么這種?prototype based programming?的語言如何實現繼承呢(OO的一大基本要素), 這也便是?prototype?的由來.

    看下面的代碼片斷:

    function foo(a, b, c) { return a*b*c; } alert(foo.length); alert(typeof foo.constructor); alert(typeof foo.call); alert(typeof foo.apply); alert(typeof foo.prototype);

    對于上面的代碼,用瀏覽器運行后你會發現:

  • length: 提供的是函數的參數個數
  • prototype: 是一個object
  • 其它三個都是function
  • 而對于任何一個函數的聲明,它都將會具有上面所述的5個property(方法或者屬性).

    下面我們主要看下prototype.

    // prototype function Person(name, gender) { this.name = name; this.gender = gender; this.whoAreYou = function(){//這個也是所謂的closure, 內部函數可以訪問外部函數的變量 var res = "I'm " + this.name + " and I'm a " + this.gender +"."; return res; }; } // 那么在由Person創建的對象便具有了下面的幾個屬性 Person.prototype.age = 24; Person.prototype.getAge = function(){ return this.age; }; flag = true; if (flag) { var fun = new Person("Tower", "male"); alert(fun.name); alert(fun.gender); alert(fun.whoAreYou()); alert(fun.getAge()); } Person.prototype.salary = 10000; Person.prototype.getSalary = function(){ return this.name + " can earn about " + this.salary + "RMB each month." ; }; // 下面就是最神奇的地方, 我們改變了Person的prototype,而這個改變是在創建fun之后 // 而這個改變使得fun也具有了相同的屬性和方法 // 繼承的意味即此 if (flag) { alert(fun.getSalary()); alert(fun.constructor.prototype.age);//而這個相當于你直接調用 Person.prototype.age alert(Person.prototype.age); }

    從上面的示例中我們可以發現,對于prototype的方法或者屬性,我們可以?動態地?增加, 而由其創建的 對象自動會?繼承?相關的方法和屬性.

    另外,每個對象都有一個?constructor?屬性,用于指向創建其的函數對象,如上例中的?fun.constructor?指向的 就是?Person.

    那么一個疑問就自然產生了,?函數對象中自身聲明的方法和屬性與prototype聲明的對象有什么差別?

    有下面幾個差別:

  • 自身聲明的方法和屬性是?靜態的, 也就是說你在聲明后,試圖再去增加新的方法或者修改已有的方法,并不會 對由其創建的對象產生影響, 也即?繼承?失敗
  • 而prototype可以動態地增加新的方法或者修改已有的方法, 從而是?動態的?,一旦?父函數對象?聲明了相關 的prototype屬性,由其創建的對象會?自動繼承?這些prototype的屬性.
  • 繼續上面的例子:

    flag = true; // 函數內部聲明的方法是靜態的,無法傳遞的 Person.school = "ISCAS"; Person.whoAreYou = function(){ return "zhutao"; };//動態更改聲明期的方法,并不會影響由其創建的對象的方法, 即所謂的 靜態 if (flag) { alert(Person.school); alert(fun.school);//輸出的是 "undefined" alert(Person.whoAreYou()); //輸出 zhutao alert(fun.whoAreYou()); // I'm Tower and I'm a male. } Person.prototype.getSalary = function(){ return "I can earn 1000000 USD"; }; if (flag) { alert(fun.getSalary());//已經繼承了改變, 即所謂的 動態 }

    既然有函數對象本身的屬性, 也有prototype的屬性, 那么是由其創建的對象是如何搜索相應的屬性的呢?

    基本是按照下面的流程和順序來進行.

  • 先去搜索函數對象本身的屬性,如果找到立即執行
  • 如果1沒有找到,則會去搜索prototype屬性,有2種結果,找到則直接執行,否則繼續搜索?父對象?的?父對象?的prototype, 直至找到,或者到達?prototype chain?的結尾(結尾會是Object對象)
  • 上面也回答如果函數對象本身的屬性與prototype屬性相同(重名)時的解決方式, 函數本身的對象?優先?.

    再看一個多重prototype鏈的例子:

    // 多重prototype鏈的例子 function Employee(name) { this.name = ""; this.dept = "general"; this.gender = "unknown"; } function WorkerBee() { this.projects = []; this.hasCar = false; } WorkerBee.prototype = new Employee; // 第一層prototype鏈 function Engineer() { this.dept = "engineer"; //覆蓋了 "父對象" this.language = "javascript"; } Engineer.prototype = new WorkerBee; // 第二層prototype鏈 var jay = new Engineer("Jay"); if (flag) { alert(jay.dept); //engineer, 找到的是自己的屬性 alert(jay.hasCar); // false, 搜索到的是自己上一層的屬性 alert(jay.gender); // unknown, 搜索到的是自己上二層的屬性 }

    上面這個示例的對象關系如下:

    結論

    javascript?的prototype給語言本身增加了很強的靈活性,但與?class based programming?相比整個思維邏輯還是有很大的不同,所以需要更多地思考和揣摩.

    而?javascript是披著c語言外衣的函數式語言?的理解自然也需要更多地思考.

    下一節我會繼續討論下?javascript?的另一個重要而且比較容易弄錯的知識?closure.

    歡迎大家留言討論.

    總結

    以上是生活随笔為你收集整理的javascript必知必会之prototype的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。