您現在的位置是:電腦技術吧?>? 故障問題 ??>??javascript 框架,javascript的基本框架??>??正文詳情

javascript 框架,javascript的基本框架

力良駿2019-12-06 10:01:59 人圍觀
簡介javascript怎么樣本文主要介紹了JavaScript框架設計和其他工廠的相關信息,非常簡單易懂。如果需要的話你可以檢查一下。JavaScript中類和繼承的出現表明JavaScrbootstrap框架

這篇文章主要介紹了javascript框架設計之類工廠的相關資料,非常淺顯易懂,有需要的小伙伴可以查看下。

類與繼承在javascript的出現,說明javascript已經達到大規模開發的門檻了,在之前是ECMAScript4,就試圖引入類,模塊等東西,但由于過分引入太多的特性,搞得javascript烏煙瘴氣,導致被否決。

不過只是把類延時到ES6.到目前為止,javascript還沒有正真意義上的類。

不過我們可以模擬類,曾近一段時間,類工廠是框架的標配,本章會介紹各種類實現,方便大家在自己的框架中或選擇時自己喜歡的那一類風格。

1.javascript對類的支持在其它語言中 ,類的實例都要通過構造函數new出來。

作為一個刻意模仿java的語言。

javascript存在new操作符,并且所有函數都可以作為構造器。

構造函數與普通的方法沒有什么區別。

瀏覽器為了構建它繁花似錦的生態圈,比如Node,Element,HTMLElement,HTMLParagraphElement,顯然使用繼承關系方便一些方法或屬性的共享,于是javascript從其它語言借鑒了原型這種機制。

Prototype作為一個特殊的對象屬性存在于每一個函數上。

當一個函數通過new操作符new出其孩子實例,這個名為實例的對象就擁有這個函數的Prototype對象所有的一切成員,從而實現實現所有實例對象都共享一組方法或屬性。

而javascript所謂的類就是通過修改這個Prototype對象,以區別原生對象及其其它定義的類。

在瀏覽器中,node這個類基于Object修改而來的,而Element則是基于Node,而HTMLElement又基于Element....相對我們的工作業務,我們可以創建自己的類來實現重用與共享。

? 1 2 3 4 5 6 7 8 9 10 11 12 function A(){ } A.prototype = { aa:aa, method:function(){ } }; var a = new A; var b = new A; console.log(a.aa === b.aa); console.log(a.method === b.method) 一般地,我們把定義在原型上的方法叫原型方法,它為所有的實例所共享,這有好也有不好,為了實現差異化,javascript允許我們直接在構造器內指定其方法,這叫特權方法。

如果是屬性,就叫特權屬性。

它們每一個實例一個副本,各不影響。

因此,我們通常把共享用于操作數據的方法放在原型,把私有的屬性放在特權屬性中。

但放于this上,還是讓人任意訪問到,那就放在函數體內的作用域內吧。

這時它就成為名副其實的私有屬性。

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 function A() { var count = 0; this.aa = aa; this.method = function() { return count; } this.obj = {} } A.prototype = { aa:aa, method:function(){ } }; var a = new A; var b = new A; console.log(a.aa === b.aa);//true 由于aa的值為基本類型,比較值 console.log(a.obj === b.obj) //false 引用類型,每次進入函數體都要重新創建,因此都不一樣。

console.log(a.method === b.method); //false 特權方法或屬性只是只是遮住原型的方法或屬性,因此只要刪掉特權方法,就能方法到同名的原型方法或屬性。

? 1 2 3 4 delete a.method; delete b.method; console.log(a.method === A.prototype.method);//true console.log(a.method === b.method); //true 用java的語言來說,原型方法與特權方法都屬性實例方法,在java中還有一種叫類方法與類屬性的東西。

它們用javascript來模擬也非常簡單,直接定義在函數上就行了。

? 1 2 3 A.method2 = function(){} //類方法 var c = new A; console.log(c.method2); //undefined 接下來,我們看下繼承的實現,上面說過,Prototype上有什么東西,它的實例就有什么東西,不論這個屬性是后來添加的,還是整個Prototype都置換上去的。

如果我們將這個prototype對象置換為另一個類的原型,那么它就輕而易舉的獲得那個類的所有原型成員。

? 1 2 3 4 5 6 7 8 9 10 function A() {}; A.prototype = { aaa : 1 } function B() {}; B.prototype = A.prototype; var b = new B; console.log(b.aaa); //= 1; A.prototype.bb = 2; console.log(b.bb) //= 2; 由于是引用著同一個對象,這意味這,我們修改A類的原型,也等同于修該了B類的原型。

因此,我們不能把一個對象賦值給兩個類。

這有兩種辦法,方法1:通過for in 把父類的原型成員逐一賦給子類的原型方法2是:子類的原型不是直接由父類獲得,先將父類的原型賦值給一個函數,然后將這個函數的實例作為子類的原型。

方法一,我們通常要實現mixin這樣的方法,有的書稱之為拷貝繼承,好處就是簡單直接,壞處就是無法通過instanceof驗證。

Prototype.js的extend方法就用來干這事。

? 1 2 3 4 5 function extend (des, source) { //des = destination for (var property in source) des[property] = source[property]; return des; } 方法二,就在原型上動腦筋,因此稱之為原型繼承。

下面是個范本? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 function A() {}; A.prototype = { aa:function(){ alert(1) } } function bridge() { }; bridge.prototype = A.prototype; function B() {} B.prototype = new bridge(); var a = new A; var b = new B; console.log(a == b) //false 證明成功分開原型 console.log(A.prototype == B.prototype) //true 子類共享父類的原型方法 console.log(a.aa === b.aa); //為父類動態添加新的方法 A.prototype.bb = function () { alert(2) } //true,繼承父類的方法 B.prototype.cc = function (){ alert(3) } //false 父類未必有子類的new實例 console.log(a.cc === b.cc) //并且它能夠正常通過javascript自帶的驗證機制instanceof console.log(b instanceof A) ;//true console.log(b instanceof B) ; //true 方法二能通過instanceof驗證,es5就內置了這種方法來實現原型繼承,它就是Object.create,如果不考慮第二個參數,它約等于下面的代碼。

? 1 2 3 4 5 Object.create = function (o) { function F() {} F.prototype = o; return new F(); } 上面的方法,要求傳入一個父類的原型作為參數,然后返回子類的原型不過,我們這樣還是遺漏了一點東西子類不只是繼承父類的遺產,還應該有自己的東西,此外,原型繼承并沒有讓子類繼承父類的成員與特權成員。

這些我們都得手動添加,如類成員,我們可以通過上面的extend方法,特權成員我們可以在子類構造器中,通過apply實現。

? 1 2 3 4 5 6 7 8 9 10 11 12 13 function inherit(init, Parent, proto){ function Son(){ Parent.apply(this, argument); //先繼承父類的特權成員 init.apply(this, argument); //在執行自己的構造器 } } //由于Object.create是我們偽造的,因此避免使用第二個參數 Son.prototype = Object.create(Parent.prototype,{}); Son.prototype.toString = Parent.prototype.toString; //處理IEbug Son.prototype.valueOf = Parent.prototype.valueOf; //處理IEbug Son.prototype.constructor = Son; //確保構造器正常指向,而不是Object extend(Son, proto) ;//添加子類的特有的原型成員 return Son; 下面,做一組實驗,測試下實例的回溯機制。

當我們訪問對象的一個屬性,那么他先尋找其特權成員,如果有同名就返回,沒有就找原型,再沒有,就找父類的原型...我們嘗試將它的原型臨時修改下,看它的屬性會變成那個。

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 function A(){ } A.prototype = { aa:1 } var a = new A; console.log(a.aa) ; //=1 //將它的所有原型都替換掉 A.prototype = { aa:2 } console.log(a.aa); //=1 //于是我們想到每個實例都有一個constructor方法,指向其構造器 //而構造器上面正好有我們的原型,javascript引擎是不是通過該路線回溯屬性呢 function B(){ } B.prototype = { aa:3 } a.constructor = B; console.log(a.aa) //1 表示不受影響 因此類的實例肯定通過另一條通道進行回溯,翻看ecma規范可知每一個對象都有一個內部屬性[[prototype]],它保存這我們new它時的構造器所引用的Prototype對象。

在標準瀏覽器與IE11里,它暴露了一個叫__proto__屬性來訪問它。

因此,只要不動__proto__上面的代碼怎么動,a.aa始終堅定不毅的返回1.再看一下,new時操作發生了什么。

1.創建了一個空對象 instance2.instance.__proto__ = intanceClass.prototype3.將構造函數里面的this = instance4.執行構造函數里的代碼5.判定有沒有返回值,沒有返回值就返回默認值為undefined,如果返回值為復合數據類型,則直接返回,否則返回this于是有了下面的結果。

? 1 2 3 4 5 6 7 8 9 10 11 12 13 function A(){ console.log(this.__proto__.aa); //1 this.aa = 2 } A.prototype = {aa:1} var a = new A; console.log(a.aa) a.__proto__ = { aa:3 } console.log(a.aa) //=2 delete a. aa; //刪除特權屬性,暴露原型鏈上的同名屬性 console.log(a.aa) //=3 有了__proto__,我們可以將原型設計繼承設計得更簡單,我們還是拿上面的例子改一改,進行試驗? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 function A() {} A.prototype = { aa:1 } function bridge() {} bridge.prototype = A.prototype; function B(){} B.prototype = new bridge(); B.prototype.constructor = B; var b = new B; B.prototype.cc = function(){ alert(3) } //String.prototype === new String().__proto__ = true console.log(B.prototype.__proto__ === A.prototype) //true console.log(b.__proto__ == B.prototype); //true console.log(b.__proto__.__proto__ === A.prototype); //true 得到父類的原型對象 因為b.__proto__.constructor為B,而B的原型是從bridge中得來的,而bride.prototype = A.prototype,反過來,我們在定義時,B.prototype.__proto__ = A.prototype,就能輕松實現兩個類的繼承.__proto__屬性已經加入es6,因此可以通過防止大膽的使用2.各種類工廠的實現。

上節我們演示了各種繼承方式的實現,但都很凌亂。

我們希望提供一個專門的方法,只要用戶傳入相應的參數,或按照一定簡單格式就能創建一個類。

特別是子類。

由于主流框架的類工廠太依賴他們龐雜的工具函數,而一個精巧的類工廠也不過百行左右相當精巧的庫,P.jshttps://github.com/jiayi2/pjs使用版:https://github.com/jiayi2/factoryjs這是一個相當精巧的庫,尤其調用父類的同名方法時,它直接將父類的原型拋在你面前,連_super也省了。

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 var P = (function(prototype, ownProperty, undefined) { return function P(_superclass /* = Object */, definition) { // handle the case where no superclass is given if (definition === undefined) { definition = _superclass; _superclass = Object; } // C is the class to be returned. // // When called, creates and initializes an instance of C, unless // `this` is already an instance of C, then just initializes `this`; // either way, returns the instance of C that was initialized. // // TODO: the Chrome inspector shows all created objects as `C` // rather than `Object`. Setting the .name property seems to // have no effect. Is there a way to override this behavior? function C() { var self = this instanceof C ? this : new Bare; self.init.apply(self, arguments); return self; } // C.Bare is a class with a noop constructor. Its prototype will be // the same as C, so that instances of C.Bare are instances of C. // `new MyClass.Bare` then creates new instances of C without // calling .init(). function Bare() {} C.Bare = Bare; // Extend the prototype chain: first use Bare to create an // uninitialized instance of the superclass, then set up Bare // to create instances of this class. var _super = Bare[prototype] = _superclass[prototype]; var proto = Bare[prototype] = C[prototype] = C.p = new Bare; // pre-declaring the iteration variable for the loop below to save // a `var` keyword after minification var key; // set the constructor property on the prototype, for convenience proto.constructor = C; C.extend = function(def) { return P(C, def); } return (C.open = function(def) { if (typeof def === 'function') { // call the defining function with all the arguments you need // extensions captures the return value. def = def.call(C, proto, _super, C, _superclass); } // ...and extend it if (typeof def === 'object') { for (key in def) { if (ownProperty.call(def, key)) { proto[key] = def[key]; } } } // if no init, assume we're inheriting from a non-Pjs class, so // default to using the superclass constructor. if (!('init' in proto)) proto.init = _superclass; return C; })(definition); } // as a minifier optimization, we've closured in a few helper functions // and the string 'prototype' (C[p] is much shorter than C.prototype) })('prototype', ({}).hasOwnProperty); 我們嘗試創建一個類:? 1 2 3 4 5 6 7 8 9 10 11 12 var Dog = P (function(proto, superProto){ proto.init = function(name) { //構造函數 this.name = name; } proto.move = function(meters){ //原型方法 console.log(this.name moved meters m.) } }); var a = new Dog(aaa) var b = new Dog(bbb); //無實例變化 a.move(1); b.move(2); 我們在現在的情況下,可以嘗試創建更簡潔的定義方式? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 var Animal = P (function(proto, superProto){ proto.init = function(name) { //構造函數 this.name = name; } proto.move = function(meters){ //原型方法 console.log(this.name moved meters m.) } }); var a = new Animal(aaa) var b = new Animal(bbb); //無實例變化 a.move(1); b.move(2); //............... var Snake = P (Animal, function(snake, animal){ snake.init = function(name, eyes){ animal.init.call(this, arguments); //調運父類構造器 this.eyes = 2; } snake.move = function() { console.log('slithering...'); animal.move.call(this, 5); //調運父類同名方法 } }); var s = new Snake(snake, 1); s.move(); console.log(s.name); console.log(s.eyes); 私有屬性演示,由于放在函數體內集中定義,因此安全可靠!? 1 2 3 4 5 6 7 8 9 10 11 var Cobra = P (Snake, function(cobra){ var age = 1;//私有屬性 //這里還可以編寫私有方法 cobra.glow = function(){ //長大 return age ; } }); var c = new Cobra(cobra); console.log(c.glow()); //1 console.log(c.glow()); //2 console.log(c.glow()); //3 以上所述就是本文的全部內容了,希望大家能夠喜歡。

版權聲明:本文由 力良駿 整理編輯。

原標題:javascript框架設計,html框架

轉載注明出處:http://www.dn9ww09s.icu/fault/15201.html

文章評論

    共有條評論來說兩句吧...

    用戶名:

    驗證碼:

作者推薦

  • 閉包是啥,閉包

    閉包是啥,閉包 相關圖片閉包和正閉包本文主要介紹了用JavaScript創建閉包的兩種方法的優缺點以及差異分析的相關資料。您可以參考JavaScript常用的兩種方法來創建閉包。構造函數方法:?1Js閉包...

  • asp本地全路徑,asp獲取路徑

    asp本地全路徑,asp獲取路徑 相關圖片asp圖片路徑格式本文主要介紹了利用asp.net獲取網站目錄物理路徑的方法。對于朋友,請參考下一頁后臺CS文件相對網站根目錄的path/view/atlas代碼,如下:striasp系統路徑代碼...

  • 數組遍歷方法,遍歷數組的三種方法

    數組遍歷方法,遍歷數組的三種方法 相關圖片javascript數組遍歷今天,一個朋友問我一個關于PHP遍歷數組的方法的問題,并告訴了她一些。順便說一下,寫一篇文章總結一下。如果摘要不完整,請首先指出,foreach()foreacjs如何遍歷...

  • 你所在的省市,所在省份

    你所在的省市,所在省份 相關圖片我所在的省份怎么填今天,我們來談談如何用PHP獲取用戶的IP地址,PHP如何根據IP判斷用戶所在的城市,以及PHP如何根據IP實現城市切換或跳轉。如何根據現有IP地址獲取其地理位所在省份...

  • 升級時,該升級關系時

    升級時,該升級關系時 相關圖片每時每秒都在升級系統本文主要介紹nginx將PHP從5.3.28升級到5.3.29時的502錯誤。對于您的朋友,請參考今天將PHP從5.3.28升級到5.3.29,發現網站無法打開版本升級相當于一個劃時帶...

  • oraclecase語句,oracle數據庫case語句

    oraclecase語句,oracle數據庫case語句 相關圖片數據庫case when語句登錄ID,用戶ID,登錄時間,url,描述,(當operatetype=0時,case operatetype=1,elsqlcase...

  • oracle col,oracle col 命令

    oracle col,oracle col 命令 相關圖片oracle set lineCol命令:主格式列的顯示形式。該命令有許多選項,如下所示:col[UMN][column | expr}[option]]選項可以是以下子句:Ali[as]aoracle round函數...

  • xml實例,xml運用

    xml實例,xml運用 相關圖片xml內容本文以實例的形式詳細描述了PHP解析XML的方法。與您分享以供參考。具體分析如下:books.xml文件如下:?123456789101213141516171xml什么文件...

  • 綠色的反色,紫色的反色

    綠色的反色,紫色的反色 相關圖片反色處理本文主要介紹了PHP將顏色轉換為反色的方法,涉及PHP操作顏色值的相關技巧。對于需要的朋友,請參考下面的例子來描述PHP將顏色轉換為相反顏色的方法。與您分享以供紋眉深...

  • 網站偽靜態,網站的偽靜態有什么用

    網站偽靜態,網站的偽靜態有什么用 相關圖片怎么滲透偽靜態網站一。Www.tuckey.org/URL Rewrite/下載URL Rewrite jar包2。將jar包復制到項目WEB-INF/WEB.xml 3。在we偽靜態網站注入方法...

熱評文章

  • oracle11g空表導出,oracle導出空數據庫

    oracle11g空表導出,oracle導出空數據庫 相關圖片oracle空白表如何在Oracle 11g中導出空表?由于Oracle 11g延遲段創建的新特性,當沒有數據插入時Oracle不會分配數據段,因此exp不能在11g數據庫中導出oracle查詢空表要2到3秒...

  • 單選,三d單選

    單選,三d單選 相關圖片3d單選網我之所以使用checkboxlist來實現無線電選擇,是因為我認為checkboxlist控件頁的顯示效果應該更好。您可以參考中提供的radiobutonlis福彩單選...

  • 閉包內存泄露,閉包為什么會造成內存泄露

    閉包內存泄露,閉包為什么會造成內存泄露 相關圖片閉包阮一峰本文主要介紹JS閉包導致內存泄漏的相關數據。可以在JS閉包中定義局部變量以供參考。但是,如果從外部調用它,特別是重復調用,將導致大量內存開銷。如何防止這種現象...

  • 用戶角色與權限,用戶角色權限具體實現

    用戶角色與權限,用戶角色權限具體實現 相關圖片用戶角色權限管理系統Oracle數據庫用戶管理Oracle權限設置一、權限分類:系統權限:系統指定用戶使用數據庫的權限。(系統權限針對用戶)。實體權限:某個權限用戶對其他用戶的表...

  • 常用代碼片段,30s代碼片段

    常用代碼片段,30s代碼片段 相關圖片有關下面代碼片段的說法一。打開一個新窗口并發送參數:發送參數:響應。Write()接收參數:字符串a=request.querystring(ID);字符串B=request.que管理常用代碼片段...

  • 9 patch,怎樣用patch

    9 patch,怎樣用patch 相關圖片patch是什么Oracle補丁也稱為Oracle補丁。有幾種Oracle修補程序。很難數這些小塊,也很難避免讓人眼花繚亂。不過,甲骨文補丁程序是有序的。Oracle提供的oppatch of...

  • c語言在線編程,c語言經典程序100例

    c語言在線編程,c語言經典程序100例 相關圖片c語言例子本文從C?程序員的角度詳細介紹了學習typescript的過程,主要針對兩種語言的異同進行了簡單的比較研究,希望對您有所幫助。Typescript發展得很好。在菜鳥教程100例...

  • datatable怎么用,datatable比較

    datatable怎么用,datatable比較 相關圖片datatable詳解本文主要介紹viewstate和datatable的動態數據輸入示例。以下代碼可用于您的朋友:%@page language=C?EnableViewStatec# datatable...

  • 批處理中如何判斷幾個文件是否存在,批處理文件中一cp命令

    批處理中如何判斷幾個文件是否存在,批處理文件中一cp命令 相關圖片ps中批處理批處理是邏輯單元的一組T-SQL語句。要將腳本分成批,可以使用go語句。一。Go語句必須是自包含的。2。Go語句使每個批獨立地發送到服務器,獨立于其他批處理程序ps中批處理...

  • jsonp如何實現,jsonp實現

    jsonp如何實現,jsonp實現 相關圖片jsonp如何實現跨域本文主要介紹了jsonp在JavaScript中的模擬實現。本文直接給出了實現代碼,其中包含了詳細的注釋。對于您的朋友,請參考“1234567891013141jsonp簡單實現...

關注微信

变脸官网查询