您好,登錄后才能下訂單哦!
本篇內容主要講解“c和javascript的區別是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“c和javascript的區別是什么”吧!
區別有:1、C語言是被編譯成機器語言,而JS是作為腳本被解釋器解釋執行;2、C語言需要程序員手動管理內存,而JS的內存是由解釋器來管理的;3、C語言通過調用系統API來實現多線程,而JS是單線程。
本教程操作環境:windows7系統、javascript1.8.5版、Dell G3電腦。
1、C語言主要是被編譯成機器語言,而JavaScript主要是作為腳本被解釋器解釋執行;
2、C語言需要程序員手動管理內存(主要指堆內存的申請和釋放),而JavaScript的內存是由解釋器來管理的;
3、JavaScript是動態類型語言,變量的數據類型在運行時仍可變化;
4、JavaScript中的函數都與其定義時可訪問到的變量組成閉包;
5、“類的繼承與多態”等面向對象的特性的支持,而JavaScript可以通過原型鏈和閉包等實現面向對象的繼承、多態和封裝,實現ECMAScript 2015及以上版本的JavaScript更是在語法層面支持類的定義;
6、C語言可以通過調用系統API來實現多線程,可以通過多線程來提高阻塞操作(主要是IO)時的CPU利用率,而JavaScript主要是單線程,JavaScript的可能阻塞的操作都由JavaScript運行時提供的異步API來完成
對于有C基礎的同學來說,學js是相當簡單的,語法類似,這里主要列一下兩者的異同,基本上記住了這些異同點,就可以上手使用js了。只需幾天,甚至一天的學習,就可以用js在QT調用百度地圖,繪制三維模型等好玩的功能。
QT開發過程中,經常要用到qss、qml、js,跟前端三件套很像(CSS/HTML/JS),這里記錄一下JS的常見語法。
C語言中的函數指針的概念,在JS中也是適用的,只不過JS中的函數指針并不是編譯級的,而是解釋級的,在底層實現上有所不同,但用法相同。
0、【變量聲明】在C語言中的變量必須先聲明,后使用;而JS允許不聲明直接用,當然也支持先聲明后使用,先使用后聲明。
1、【賦值與賦引用】js中的變量賦值時,除了基本類型是拷貝賦值以外,"其他"都是賦引用(所謂"其他",其實都是JS中的對象變量)。C語言的賦值,都是拷貝賦值,除非你顯式地指定要賦引用。
2、【回調】兩者都有回調函數的概念,而且函數名就是回調變量名,C和JS都是如此。
3、【自調用】。JS可以在定義函數的時候,立即調用一次。語法為:
無參函數示例 (function fooA (){ //這里是函數體 })(); 有參函數示例: (function fooB(var a){ //這里是函數體 })(5);
就是把整個函數定義,用小括號A括住(這就相當于拿到了該函數的函數指針),然后后面再加一個括號B(這就相當于執行這個函數),后面的小括號B,可以填參數。而且這里的函數名可省略不寫。
4、【函數內定義函數】JS允許在函數內部繼續定義函數。
5、【閉包】
這個概念比較新鮮,在C/C++中沒見過,通過閱讀JS教程發現這東西也簡單的很,就是起的名字太唬人了,簡單來講,這種編程手法,可以使某個函數擁有局部靜態變量。
一般來說,JS中變量的作用域,與C是一致的,函數內的變量,在函數外是無法訪問的,除非你用函數的形參或者返回值,把局部變量的指針,弄到外面,這樣函數外面的代碼就可以通過指針操作某個函數內部局部靜態變量了。與此類似,JS中也有這種手法,這種手法的名字叫閉包。區別在于,C從函數中扔出的是某個局部靜態變量的指針,而JS扔出的是能夠操作這個局部變量的的函數的指針。
為了對比,先來一個C語言版本的“閉包”:
uint8_t *getBuf(void) { static uint8_t buf[1024]; return buf; } void sendCmd() { uint8_t *cmdBuf = getBuf(void); cmdBuf[0] = 0xA5; cmdBuf[1] = 0xFF; .... send(cmdBuf, 10); }
getBuf函數中有一個局部靜態數組buf,本來程序的其他代碼是無法訪問到它的,但是我們通過該函數的返回值,將其首地址送出來,就實現了外部代碼對該數組的訪問。例如sendCmd函數就使用了一下這個數組。
下面是JS版本:
場景(1):函數A內定義了變量a和函數B,顯然B是可以訪問a的,如何才能讓A外面的代碼訪問到a呢?有2種思路,一種是返回a的引用,另一種是閉包。返回引用就不說了,因為a在A執行完后內存會被釋放,返回a的引用也無法訪問a。
var aRef = (function A(){ var a = 2; return function B(){ return a++; } })(); alert(aRef()); alert(aRef());
上述代碼的效果為,彈出提示框,內容為數字2, 然后再次彈出提示框,內容為數字3。其中函數名A和函數名B均可不寫。
我們來分析一下上述代碼,首先函數A是個自調用函數(也可以不自調用,后面有例子),所以A里面變量a立即被賦值為2,函數A的返回值為函數B的函數指針,所以變量aRef就是個函數指針,以后調用aRef( ),就相當于調用了函數B( )。而B( )的返回值為a++。按照JS的設計機制,這種情形下的變量a將會常駐內存,這就是實現了讓函數A擁有局部靜態變量,而這個局部靜態變量,只能被A返回的函數指針(也即函數B)修改。
基于上述分析,我們可以把上述代碼改成這樣,更容易閱讀:
var aRef = (function A(){ var a = 2; function B(){ return a++; } return B; })(); 也可以改成這樣: function A(){ var a = 2; function B(){ return a++; } return B; } var aRef = A();//A沒有進行自調用,只能在這里調一次,才能獲取到B的函數指針
情形2:經典的JS定時器閉包。題目:使用for循環,每秒打印出for當前的值。
錯誤寫法:
for(var i = 1; i <= 5; i++) { setTimeout(function(){ alert(i); }, 1000); }
執行的效果是,連續彈出5次數字5,而不是預想的依次彈出12345。原因是,第一次執行定時器的回調函數前,i的值就已經變成5了,后續4次定時回調,i的值也是5.
正確寫法:
for(var i = 1; i <= 5; i++) { (function(a){ setTimeout(function(){alert(a);}, 1000); })(i); }
這里使用了一個匿名的自調用函數(為了敘述方便,我下面稱之為out函數),在函數內部又聲明了匿名的定時器回調函數(為了敘述方便,我下面稱之為in函數),因此使得in函數成了閉包函數,從而使得out函數的局部變量a常駐內存了。
為了更清楚de看明白它的原理,我們再把這段代碼改成這樣,增強可讀性:
function outFunc(a){ function inFunc(){ alert(a); } setTimeout(inFunc, 1000); } for(i = 0; i < 4; i++) { outFunc(i); }
這段代碼看起來清晰了,可以一目了然地看出其中的閉包語法。
總結一下閉包就是:一旦執行了閉包函數所在的外部函數,那么這個外部函數所維護的局部變量,將會常駐內存。
最后來一個實例應用,看看閉包在實際場景中是如何應用的。題目:有如下C語言函數,請把它改成js版。
uint32_t readVol(void) { static uint8_t callCnt = 0; callCnt++; return callCnt; }
這個C函數的功能很簡單,就是每次調用時,會返回該函數被調的次數,也即readVol這個函數擁有自己的局部靜態變量。用js實現如下:
var readVol = (function () { var callCnt = 0; return function() { callCnt++; return callCnt; } })();
這個readVol函數與C語言的readVol函數功能完全一致。
到此,相信大家對“c和javascript的區別是什么”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。