溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

c和javascript的區(qū)別是什么

發(fā)布時(shí)間:2021-06-16 10:35:59 來源:億速云 閱讀:283 作者:chen 欄目:web開發(fā)

本篇內(nèi)容主要講解“c和javascript的區(qū)別是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“c和javascript的區(qū)別是什么”吧!

區(qū)別有:1、C語言是被編譯成機(jī)器語言,而JS是作為腳本被解釋器解釋執(zhí)行;2、C語言需要程序員手動(dòng)管理內(nèi)存,而JS的內(nèi)存是由解釋器來管理的;3、C語言通過調(diào)用系統(tǒng)API來實(shí)現(xiàn)多線程,而JS是單線程。

本教程操作環(huán)境:windows7系統(tǒng)、javascript1.8.5版、Dell G3電腦。

1、C語言主要是被編譯成機(jī)器語言,而JavaScript主要是作為腳本被解釋器解釋執(zhí)行;

2、C語言需要程序員手動(dòng)管理內(nèi)存(主要指堆內(nèi)存的申請和釋放),而JavaScript的內(nèi)存是由解釋器來管理的;

3、JavaScript是動(dòng)態(tài)類型語言,變量的數(shù)據(jù)類型在運(yùn)行時(shí)仍可變化;

4、JavaScript中的函數(shù)都與其定義時(shí)可訪問到的變量組成閉包;

5、“類的繼承與多態(tài)”等面向?qū)ο蟮奶匦缘闹С?,而JavaScript可以通過原型鏈和閉包等實(shí)現(xiàn)面向?qū)ο蟮睦^承、多態(tài)和封裝,實(shí)現(xiàn)ECMAScript 2015及以上版本的JavaScript更是在語法層面支持類的定義;

6、C語言可以通過調(diào)用系統(tǒng)API來實(shí)現(xiàn)多線程,可以通過多線程來提高阻塞操作(主要是IO)時(shí)的CPU利用率,而JavaScript主要是單線程,JavaScript的可能阻塞的操作都由JavaScript運(yùn)行時(shí)提供的異步API來完成

對于有C基礎(chǔ)的同學(xué)來說,學(xué)js是相當(dāng)簡單的,語法類似,這里主要列一下兩者的異同,基本上記住了這些異同點(diǎn),就可以上手使用js了。只需幾天,甚至一天的學(xué)習(xí),就可以用js在QT調(diào)用百度地圖,繪制三維模型等好玩的功能。

QT開發(fā)過程中,經(jīng)常要用到qss、qml、js,跟前端三件套很像(CSS/HTML/JS),這里記錄一下JS的常見語法。

C語言中的函數(shù)指針的概念,在JS中也是適用的,只不過JS中的函數(shù)指針并不是編譯級(jí)的,而是解釋級(jí)的,在底層實(shí)現(xiàn)上有所不同,但用法相同。

0、【變量聲明】在C語言中的變量必須先聲明,后使用;而JS允許不聲明直接用,當(dāng)然也支持先聲明后使用,先使用后聲明。

1、【賦值與賦引用】js中的變量賦值時(shí),除了基本類型是拷貝賦值以外,"其他"都是賦引用(所謂"其他",其實(shí)都是JS中的對象變量)。C語言的賦值,都是拷貝賦值,除非你顯式地指定要賦引用。

2、【回調(diào)】兩者都有回調(diào)函數(shù)的概念,而且函數(shù)名就是回調(diào)變量名,C和JS都是如此。

3、【自調(diào)用】。JS可以在定義函數(shù)的時(shí)候,立即調(diào)用一次。語法為:

無參函數(shù)示例
(function fooA (){
            //這里是函數(shù)體
        })();
有參函數(shù)示例:
(function fooB(var a){
            //這里是函數(shù)體
        })(5);

就是把整個(gè)函數(shù)定義,用小括號(hào)A括?。ㄟ@就相當(dāng)于拿到了該函數(shù)的函數(shù)指針),然后后面再加一個(gè)括號(hào)B(這就相當(dāng)于執(zhí)行這個(gè)函數(shù)),后面的小括號(hào)B,可以填參數(shù)。而且這里的函數(shù)名可省略不寫。

4、【函數(shù)內(nèi)定義函數(shù)】JS允許在函數(shù)內(nèi)部繼續(xù)定義函數(shù)。

5、【閉包】

這個(gè)概念比較新鮮,在C/C++中沒見過,通過閱讀JS教程發(fā)現(xiàn)這東西也簡單的很,就是起的名字太唬人了,簡單來講,這種編程手法,可以使某個(gè)函數(shù)擁有局部靜態(tài)變量。

一般來說,JS中變量的作用域,與C是一致的,函數(shù)內(nèi)的變量,在函數(shù)外是無法訪問的,除非你用函數(shù)的形參或者返回值,把局部變量的指針,弄到外面,這樣函數(shù)外面的代碼就可以通過指針操作某個(gè)函數(shù)內(nèi)部局部靜態(tài)變量了。與此類似,JS中也有這種手法,這種手法的名字叫閉包。區(qū)別在于,C從函數(shù)中扔出的是某個(gè)局部靜態(tài)變量的指針,而JS扔出的是能夠操作這個(gè)局部變量的的函數(shù)的指針。

為了對比,先來一個(gè)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函數(shù)中有一個(gè)局部靜態(tài)數(shù)組buf,本來程序的其他代碼是無法訪問到它的,但是我們通過該函數(shù)的返回值,將其首地址送出來,就實(shí)現(xiàn)了外部代碼對該數(shù)組的訪問。例如sendCmd函數(shù)就使用了一下這個(gè)數(shù)組。

下面是JS版本:

場景(1):函數(shù)A內(nèi)定義了變量a和函數(shù)B,顯然B是可以訪問a的,如何才能讓A外面的代碼訪問到a呢?有2種思路,一種是返回a的引用,另一種是閉包。返回引用就不說了,因?yàn)閍在A執(zhí)行完后內(nèi)存會(huì)被釋放,返回a的引用也無法訪問a。

var aRef = (function A(){
            var a = 2;
            return function B(){
                return a++;
            }
            })();

alert(aRef());
alert(aRef());

上述代碼的效果為,彈出提示框,內(nèi)容為數(shù)字2, 然后再次彈出提示框,內(nèi)容為數(shù)字3。其中函數(shù)名A和函數(shù)名B均可不寫。

我們來分析一下上述代碼,首先函數(shù)A是個(gè)自調(diào)用函數(shù)(也可以不自調(diào)用,后面有例子),所以A里面變量a立即被賦值為2,函數(shù)A的返回值為函數(shù)B的函數(shù)指針,所以變量aRef就是個(gè)函數(shù)指針,以后調(diào)用aRef( ),就相當(dāng)于調(diào)用了函數(shù)B( )。而B( )的返回值為a++。按照J(rèn)S的設(shè)計(jì)機(jī)制,這種情形下的變量a將會(huì)常駐內(nèi)存,這就是實(shí)現(xiàn)了讓函數(shù)A擁有局部靜態(tài)變量,而這個(gè)局部靜態(tài)變量,只能被A返回的函數(shù)指針(也即函數(shù)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沒有進(jìn)行自調(diào)用,只能在這里調(diào)一次,才能獲取到B的函數(shù)指針

情形2:經(jīng)典的JS定時(shí)器閉包。題目:使用for循環(huán),每秒打印出for當(dāng)前的值。

錯(cuò)誤寫法:

for(var i = 1; i <= 5; i++)
{
    setTimeout(function(){
        alert(i);
    }, 1000);
}

執(zhí)行的效果是,連續(xù)彈出5次數(shù)字5,而不是預(yù)想的依次彈出12345。原因是,第一次執(zhí)行定時(shí)器的回調(diào)函數(shù)前,i的值就已經(jīng)變成5了,后續(xù)4次定時(shí)回調(diào),i的值也是5.

正確寫法:

for(var i = 1; i <= 5; i++)
{
    (function(a){
        setTimeout(function(){alert(a);}, 1000);
    })(i);
}

這里使用了一個(gè)匿名的自調(diào)用函數(shù)(為了敘述方便,我下面稱之為out函數(shù)),在函數(shù)內(nèi)部又聲明了匿名的定時(shí)器回調(diào)函數(shù)(為了敘述方便,我下面稱之為in函數(shù)),因此使得in函數(shù)成了閉包函數(shù),從而使得out函數(shù)的局部變量a常駐內(nèi)存了。

為了更清楚de看明白它的原理,我們再把這段代碼改成這樣,增強(qiáng)可讀性:

function outFunc(a){
    function inFunc(){
        alert(a);
    }
    setTimeout(inFunc, 1000);
}

for(i = 0; i < 4; i++)
{
    outFunc(i);
}

這段代碼看起來清晰了,可以一目了然地看出其中的閉包語法。

總結(jié)一下閉包就是:一旦執(zhí)行了閉包函數(shù)所在的外部函數(shù),那么這個(gè)外部函數(shù)所維護(hù)的局部變量,將會(huì)常駐內(nèi)存。

最后來一個(gè)實(shí)例應(yīng)用,看看閉包在實(shí)際場景中是如何應(yīng)用的。題目:有如下C語言函數(shù),請把它改成js版。

uint32_t readVol(void)
{
    static uint8_t callCnt = 0;
    callCnt++;
    return callCnt;
}

這個(gè)C函數(shù)的功能很簡單,就是每次調(diào)用時(shí),會(huì)返回該函數(shù)被調(diào)的次數(shù),也即readVol這個(gè)函數(shù)擁有自己的局部靜態(tài)變量。用js實(shí)現(xiàn)如下:

    var readVol = (function ()
	{
		var callCnt = 0;
		return function()
		{
			callCnt++;
			return callCnt;
		}		
	})();

這個(gè)readVol函數(shù)與C語言的readVol函數(shù)功能完全一致。

到此,相信大家對“c和javascript的區(qū)別是什么”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI