重慶分公司,新征程啟航
為企業提供網站建設、域名注冊、服務器等服務
為企業提供網站建設、域名注冊、服務器等服務
JavaScript基礎之對象
創新新互聯,憑借10余年的網站設計、成都網站制作經驗,本著真心·誠心服務的企業理念服務于成都中小企業設計網站有近千家案例。做網站建設,選創新互聯。
從2004年下半年開始學習Web編程至今3年有余。從HTML,asp開始到現在的VS2008一路學過來,其中學的最多的還是服務器端編程,對客戶端編程的學習還是不成系統。雖然在很多個系統里面應用過腳本,有些還起到了比較重要的作用。但一直是只知其然不知其所以然,用的是小心翼翼。現在腳本編程從以前的"雕蟲小技"變成了一個Web開發不可或缺的元素,其地位大大提高了,特別是Ajax興起之后它更是"炙手可熱"了。鑒于此種情況及自己對腳本編程的熱愛,于是就系統地學習一下腳本。
學習是理解和記憶的過程。在理解和記憶的過程中必不可少地就需要一些輔助的記錄,于是我就將自己的學習記錄寫成隨筆。一來是幫助自己理解和記憶,二來也給其它熱愛腳本的同志一些參考。
1 JavaScript對象
ECMA-262將對象(object)定義為"屬性的無序集合,每個屬性存放一個原始值、對象或函數"(unordered collection of properties each of which contains a primitive value, object, or function)。這意味著對象是無特定順序的值的數組。在ECMAScript中,對象由特性(Attribute)構成,特性可以是原始值,也可以是引用值。如果特性存放的是函數,它將被看作對象的方法(Method),否則該特性被看作屬性(Property)。
2 對象的廢除
ECMAScript有無用存儲單元收集程序(就像C#的垃圾收集器),意味著不必專門銷毀對象來釋放內存。當再沒有對對象的引用時,該對象就被廢除了。運行無用存儲單元收集程序時,所有廢除的對象都會被銷毀。每當函數執行完它的代碼,無用存儲單元收集程序都會運行,釋放所有的局部變量,還有在一些其它不可預知的情況下,無用存儲單元收集程序也會運行。
把對象的所有引用都設置為null,可以強制性的廢除對象。例如:
Var oObject=new Object();
// 程序邏輯
oObject=null;
當變量oObject設置為null后,對第一個創建的對象的引用就不存在了。這意味著下次運行無用存儲單元收集程序時,該對象將被銷毀。
每用完一個對象后,就將其廢除,來釋放內存,這是個好習慣。這樣還確保不再使用已經不能訪問的對象,從而防止程序設計錯誤的出現。此外,舊的瀏覽器(如IE)沒有完全的無用存儲單元收集程序,所以卸載頁面時,對象可能不能被正確地銷毀。以前IE6就有這樣的詬病,當頁面被關閉后對象還是沒有被釋放,所以總是會導致內存溢出的錯誤。廢除對象和它所有的特性是確保內存正確使用的最好方法。
3 對象的類型
JavaScript中對象分為:本地對象(native object)、內置對象(built-in object)、宿主對象(host object)。其中本地對象和宿主對象大家一般用的比較多,比較熟。這里我就重點說明一下內置對象。
ECMA-262把內置對象定義為"由ECMAScript實現提供的、獨立于宿主環境的所有對象,在ECMAScript程序開始執行時出現"(any object supplied by an ECMAScript implementation, independent of the host environment, which is present at the start of the execution of an ECMAScript program.)。這意味著開發者不必明確實例化內置對象,它已經被實例化了。但ECMAScript只定義了兩個內置對象:
3.1 Math對象
Math對象就是解決數學問題的所有公式。這個在各種編程語言中都有類似的實現,就不做介紹了。
3.2 Global對象
園子里很多搞ASP.net的,相信大家對其中的Global.asax非常熟悉了。但這個對象在ECMAScript中卻比較特殊。因為它實際上根本就不存在。如果嘗試編寫下面的代碼去實例化它,將得到錯誤:
Var _global=new Global();
錯誤消息顯示Global不是對象,但上文卻說Global是一個內置對象,這不就自相矛盾了嗎?不矛盾。這里需要理解的主要概念是,在ECMAScript中,不存在獨立的函數,所有的函數都必須是某個對象的方法。ECMAScript中常用的函數例如isNaN()、isFinite()等,看起來都像獨立的函數。實際上,它們都是Global對象的方法。而且Global對象的方法還不止這些。
4 定義類或對象
雖然ECMAScript越來越正規化了,但創建對象的方法卻被置之不理。在高級的編程語言(如C#)中,創建對象的方法被明確的定義了。所以不會有太大的分歧。但在腳本語言中創建對象的方法就是多種多樣了。
4.1 工廠方式
由于對象的屬性可在對象創建后動態定義,所以許多開發者都在初次引入JavaScript時編寫類似下面的代碼:
Var oCar=new Object();
oCar.color="red";
oCar.doors=4;
oCar.mpg=23;
oCar.showColor=function(){alert(this.color);};
在這段代碼中,創建對象car。然后給它設置幾個屬性:它的顏色是紅色,有四個門,每加侖油23英里。最后一個屬性是指向函數的指針,意味著該屬性其實是個方法。執行這段代碼后,就可以使用對象car了。可是要創建多個car實例就麻煩了。
要解決此問題,開發者可以創建并返回特定類型的對象的工廠函數。例如,函數CreateCar()可用于封裝前面列出的創建car對象的操作:
Function createCar()
{
Var oTempCar=new Object();
oTempCar.color="red";
oTempCar.doors=4;
oTempCar.mpg=23;
oTempCar.showColor=function(){alert(this.color)};
return oTempCar;
}
Var oCar1=createCar();
Var oCar2=createCar();
這里,前面的所有代碼都包含在createCar()函數中,此外還有一行額外的代碼,返回Car對象作為函數值。調用此函數時,將創建新對象,并賦予它所有必要的屬性,復制出一個前面說明的car對象。使用該方法,可以容易地創建car對象的兩個版本,他們的屬性完全一樣。當然,還可以修改creatCar()函數,給它傳遞各個屬性的默認值,而不是賦予屬性默認值:
Function createCar(sColor,iDoors,iMpg)
{
Var oTempCar=new Object();
oTempCar.color= sColor;
oTempCar.doors= iDoors;
oTempCar.mpg= iMpg;
oTempCar.showColor=function(){alert(this.color)};
return oTempCar;
}
Var oCar1=createCar("red",4,23);
Var oCar2=createCar("blue",2,26);
oCar1.showColor(); // 輸出"red"
oCar2.showColor(); // 輸出"blue"
給createCar()函數加上參數,即可為要創建的car對象的color、doors和mpg屬性賦值。使這兩個對象具有相同的屬性,卻有不同的屬性值。但這里有個問題:每次調用函數createCar(),都要創建新函數showColor(),意味著每個對象都有自己的showColor()版本。事實上,每個對象用的都是同一段代碼。這樣的定義方法還有一個如下的變形:
Function Car(sColor,iDoors,iMpg)
{
this.color= sColor;
this.doors= iDoors;
this.mpg= iMpg;
this.showColor=function(){alert(this.color)};
}
Var oCar1=new Car("red",4,23);
Var oCar2=new Car("blue",2,26);
oCar1.showColor(); // 輸出"red"
oCar2.showColor(); // 輸出"blue"
這個方法和上一個方法有個一樣的缺陷:重復的創建了showColor()函數。為了解決這個缺陷我們可以用下面的方法。
4.2 原型方式
該方法利用了對象的Prototype屬性。用空構造函數來設置類名,然后所有的屬性和方法都被直接賦予prototype屬性:
Function Car()
{}
Car.prototype.color="red";
Car.prototype.doors=4;
Car.prototype.mpg=23;
Car.prototype.showColor=function(){alert(this.color)};
Var oCar1=new Car();
Var oCar2=new Car();
使用這個方法可以解決重復創建showColor()函數,但又會有新的問題,考慮下面的例子:
Function Car()
{}
Car.prototype.color="red";
Car.prototype.doors=4;
Car.prototype.mpg=23;
Car.prototype.drivers=new Array("Mike","Sue");
Car.prototype.showColor=function(){alert(this.color)};
Var oCar1=new Car();
Var oCar2=new Car();
oCar1.drivers.push("Matt");
alert(oCar1.drivers); // 輸出"Mike,Sue,Matt"
alert(oCar2.drivers); // 輸出"Mike,Sue,Matt"
這里,屬性drivers是指向Array對象的指針。改變指針指向的內容,所有的實例都會改變。看來這種方法也不可取
4.3 混合方式
這種方式就是用構造函數定義對象的所有非函數屬性,用原型方式定義對象的函數屬性(方法)。結果所有的函數只創建一次,而每個對象都具有自己的對象屬性實例。
Function Car(sColor,iDoors,iMpg)
{
this.color= sColor;
this.doors= iDoors;
this.mpg= iMpg;
Car.drivers=new Array("Mike","Sue");
}
Car.prototype.showColor=function(){alert(this.color)};
Var oCar1=new Car("red",4,23);
Var oCar2=new Car("blue",3,25);
oCar1.drivers.push("Matt");
alert(oCar1.drivers); // 輸出"Mike,Sue,Matt"
alert(oCar2.drivers); // 輸出"Mike,Sue"
這種方式是ECMAScript主要采用的方式,它具有其他方式的特性,卻沒有它們的缺陷。在實際編程中應用的也是最多了。
另外還有JSON創建方式。其創建的方式如下:
var Car =
{
color: "red",
doors: 4,
mpg: 23,
drivers: [{name: "Mike", age: 20, Married: false}, {name: "Sue", age: 30, Marred: true}],
showColor: function() {alert(this.color)}
};
這種創建對象的方式也比較優雅。可作為Ajax返回的文本,然后用eval()函數將其還原成一個對象。著名的腳本框架JQuery就有專門接收返回文本為JSON對象的異步方法。
定義 腳本語言,腳本語言或擴建的語言,又叫動態語言。是一種編程語言控制軟件應用程序。 [編輯本段]概述 計算機語言是為了各種目的和任務而開發的,一個常見任務就是把各種不同的已有組件連接起來以完成相關任務。大多腳本語言共性是:良好的快速開發,高效率的執行,解釋而非編譯執行,和其它語言編寫的程序組件之間通信功能很強大。 許多腳本語言用來執行一次性任務,尤其是系統管理方面。它可以把服務組件粘合起來,因此被廣泛用于GUI創建或者命令行,操作系統通常提供一些默認的腳本語言,即通常所謂shell腳本語言。 腳本通常以文本(如ASCII)保存,只在被調用時進行解釋或編譯。 有些腳本是為了特定領域設計的,但通常腳本都可以寫更通用的腳本。在大型項目中經常把腳本和其它低級編程語言一起使用,各自發揮優勢解決特定問題。腳本經常用于設計互動通信,它有許多可以單獨執行的命令,可以做很高級的操作,(如在傳統的Unix shell (sh)中,大多操作就是程序本身。) 這些高級命令簡化了代碼編寫過程。諸如內存自動管理和溢出檢查等性能問題可以不用考慮。在更低級或非腳本語言中,內存及變量管理和數據結構等耗費人工,為解決一個給定問題需要大量代碼,當然這樣能夠獲得更為細致的控制和優化。腳本缺少優化程序以提速或者降低內存的伸縮性。 綜上所述,腳本編程速度更快,且腳本文件明顯小于如同類C程序文件。這種靈活性是以執行效率為代價的。腳本通常是解釋執行的,速度可能很慢,且運行時更耗內存。在很多案例中,如編寫一些數十行的小腳本,它所帶來的編寫優勢就遠遠超過了運行時的劣勢,尤其是在當前程序員工資趨高和硬件成本趨低時。 然而,在腳本和傳統編程語言之間的界限越來越模糊,尤其是在一系列新語言及其集成暢出現時。在一些腳本語言中,有經驗的程序員可以進行大量優化工作。在大多現代系統中通常有多種合適的腳本語言可以選擇,所以推薦使用多種語言(包括C或匯編語言)編寫一種腳本。 [編輯本段]與其他編程語言的關系及特點 1.腳本語言(JavaScript,VBscript等)介于HTML和C,C++,Java,C#等編程語言之間。 HTML通常用于格式化和鏈結文本。而編程語言通常用于向機器發出一系列復雜的指令。 2.腳本語言與編程語言也有很多相似地方,其函數與編程語言比較相象一些,其也涉及到變量。與編程語言之間最大的區別是編程語言的語法和規則更為嚴格和復雜一些. 3.與程序代碼的關系:腳本也是一種語言,其同樣由程序代碼組成。 注:腳本語言一般都有相應的腳本引擎來解釋執行。 他們一般需要解釋器才能運行。Python、JAVASCRIPT,ASP,PHP,PERL,Nuva都是腳本語言。C/C++編譯、鏈接后,可形成獨立執行的exe文件。 4.腳本語言是一種解釋性的語言,例如Python、vbscript,javascript,installshield script,ActionScript等等,它不象c\c++等可以編譯成二進制代碼,以可執行文件的形式存在. 腳本語言不需要編譯,可以直接用,由解釋器來負責解釋。 5.腳本語言一般都是以文本形式存在,類似于一種命令. 舉個例子說,如果你建立了一個程序,叫aaa.exe,可以打開.aa為擴展名的文件. 你為.aa文件的編寫指定了一套規則(語法),當別人編寫了.aa文件后,你的程序用這種規則來理解編寫人的意圖,并作出回應.那么,這一套規則就是腳本語言. [編輯本段]計算機腳本語言程序舉例 (1)JavaScript: ①用于HTML中: alert("Hello World") ②用于WSH中: WScript.Echo("Hello World") (2)ASP: % Response.Write("Hello, world!") % 或者: % strHelloWorld = "Hello, world!" % %= strHelloWorld % 或者簡單地寫成: %= "Hello, world!" % (3)PHP: ?php echo 'Hello, world!'; print 'Hello, world!'; ? 或者 ?= "Hello World!"?
如果幫助到您,請記得采納為滿意答案哈,謝謝!祝您生活愉快! vae.la
那個網友采納的答案都沒明白你問的是什么意思。所以我就拋個磚。
我沒法在這里非常細致的一點一點的對比兩個語言的優缺點,自己 Google 一下一大片,只是我剛好主要用這兩種語言開發,所以說說我自己的看法。
我覺得單從語言的設計上來說,JavaScript 明顯要優于 PHP。
JavaScript 在之前一直令大家所詬病的多在其瀏覽器端使用時的安全性、不同平臺的特性不統一等。但是這些其實并不是 JavaScript 語言本身的問題,而且隨著 NodeJS 的出現以及 Ecma 新標準的推動,現在的這些問題已經不是問題,或者即將不是問題。另外,很多人也認為原型繼承也是 JavaScript 糟粕的地方之一,但是我覺得沒有那么早,何況 ES6 已經支持像創建正常語言的語法一樣創建 class。再就是 JavaScript 有很多讓人疑惑不解的地方,例如 this 指針的很多特性,變量類型的轉換,很多符號的二義性等等。這些問題有些在新的標準中有解決,有一些依然存在。
JavaScript 有一個很好的有點就是最近兩年革新的非常快,新的標準快速吸納了很多現代語言的優秀語法特性,社區也非常活躍。
PHP 是一個讓大家噴了多年的語言,雖然用的人很多,但是不得不承認其存在很多問題。很多人認為其設計的如同屎一般。關于 PHP 的問題,建議自行 Google。
但是語言也都在發展,PHP 這幾年也做了不少革新,特別是 PHP7不僅僅大幅的提升了性能,而且也給之后的 PHP 發展帶來了更多新的可能。
我了解過幾種語言,對 JavaScript 和 PHP 比較熟悉,Swift 和 Python 也都有接觸。這幾種語言里面,我最喜歡的是 JavaScript 和 Swift。
1.性能Python的在性能上比較飽受詬病。不過在ML這個問題卻不成立,為什么呢?稍微觀察就可以發現,流行的基于Python的機器學習庫大多不是用純Python寫成的。比如很火的scikit-learn,其核心算法大多都是用Cython實現的,一種Python與C的混合語言。Python在這里起著“膠水”的作用,封裝更高級的接口。2.快速開發實際上機器學習的算法不太注重快速開發,甚至是站在其反面。核心一旦實現,就基本上很少有人會去碰了,因為很難保證算法的正確性。這和web開發有著本質的不同,后者是在選定一個框架的基礎上,進行功能上的“橫向”拓展。因為有成熟的范式可以遵循,所以能做到“快速”。相比之下,機器學習就完全是另一個層次的東西了。