中文字幕理论片,69视频免费在线观看,亚洲成人app,国产1级毛片,刘涛最大尺度戏视频,欧美亚洲美女视频,2021韩国美女仙女屋vip视频

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
Javascript中的變量以及如何定義靜態(tài)變量 | 盛夏蓮花

Javascript的變量只有全局作用域和函數(shù)作用域,沒有其它語言中常見的塊作用域,也就是在()和{}作用域中的變量。

變量從其聲明(var myVar)或首次賦值(此前未聲明)之處起開始處進(jìn)入其生命期。有些文章認(rèn)為在Javascript函數(shù)中,變量即用即聲明是bad practice,因?yàn)橹灰诤瘮?shù)中任意地方聲明了某個(gè)變量,該變量即在函數(shù)開頭處就進(jìn)入了其生命期,因此best practice是前向聲明。但是下面代碼的運(yùn)行結(jié)果(在firebug中)顯示變量仍然是從其聲明處進(jìn)入生命期的。

  1. function sayHi2(){
  2. console.log(myVar); //this line will comlain myVar is not defined
  3. var myVar = 20;
  4. console.log("after:" + myVar);
  5. }
  6.  
  7. sayHi2();

通過下面兩種方式產(chǎn)生一個(gè)全局作用域的變量:

1. 在任何函數(shù)體之外通過var關(guān)鍵字聲明的變量;

2. 在任何地方(函數(shù)體內(nèi)或者函數(shù)體外),對(duì)一個(gè)從未聲明過的標(biāo)識(shí)符賦值,從而使其成為一個(gè)變量。

全局變量實(shí)際上是宿主對(duì)象的成員變量。比如在瀏覽器環(huán)境下,全局變量myVar實(shí)際上等于window.myVar。

構(gòu)造函數(shù)中的變量

Javascript中的構(gòu)造函數(shù)并沒有特別的形式和限定。一般程序員會(huì)將一個(gè)函數(shù)名的首字母置為大寫,如果他想將該函數(shù)當(dāng)作構(gòu)造函數(shù)使用的話。下面是構(gòu)造函數(shù)一例:

  1. var Person = function() {
  2. var a = 0; //聲明了一個(gè)局部變量,在構(gòu)造函數(shù)外任何地方都無法使用它
  3. b = 1; //產(chǎn)生了一個(gè)全局變量
  4. this.c = 2; //產(chǎn)生了一個(gè)成員變量
  5. this.funcA = function(){console.log("funcA");}; //成員函數(shù)
  6. function funcB(){ //函數(shù)也是對(duì)象。因此,這個(gè)定義實(shí)際上聲明了一個(gè)局部變量,構(gòu)造函數(shù)以外任何地方都無法引用它
  7. console.log("funcB");
  8. }
  9. };
  10.  
  11. var p = new Person ();
  12. console.dir(p);

一般說來,構(gòu)造函數(shù)只應(yīng)該包含簡單的賦值和函數(shù)定義(注:函數(shù)定義一般應(yīng)移出構(gòu)造函數(shù),并聲明在其prototype屬性上)。上例的目的是為了演示函數(shù)中的變量作用域。

  1. function foo() {
  2. foo.counter = foo.counter || 0; // 將計(jì)數(shù)器初始化為0
  3. foo.counter++;
  4.  
  5. console.log(foo.counter);
  6. }
  7.  
  8. for (var i = 0; i <=5; i++){
  9. foo();
  10. }

上述代碼運(yùn)行結(jié)果(在firebug控制臺(tái)中)是列出了變量c和函數(shù)funcA。注意,上述示例中var a和函數(shù)funcB的聲明仍然可能是有意義的。它們可以用作構(gòu)造函數(shù)中使用的輔助變量和輔助函數(shù)。

在C語言,以及c++在某些情況下,從函數(shù)中返回一個(gè)非基本類型的局部變量通常是不允許的。因?yàn)閏/c++是按值傳遞,當(dāng)函數(shù)結(jié)束時(shí),其堆棧被復(fù)位。基本類型(如int,char)其值可以直接按值傳遞出去,不會(huì)產(chǎn)生任何問題,但其它變量如果是按地址傳遞的話,其地址由于在堆棧中,因此該變量的數(shù)據(jù)會(huì)隨堆棧的復(fù)位而消亡。但在Javascript,Java和C#等語言中,這樣做是允許的。理論上它們?nèi)匀皇莻髦敌驼Z言,但由于它們傳遞的是變量的引用,而變量始終產(chǎn)生在堆上(沒有明確的語言規(guī)范和教程說明Javascript的變量位置),因此函數(shù)結(jié)束后,變量要么被回收(沒有被引用的情況下),要么繼續(xù)有效。

靜態(tài)變量

一眾語言都支持靜態(tài)變量,但遺憾的是Javascript并不支持。好在仍然有方法可以模擬出靜態(tài)變量。靜態(tài)變量的實(shí)質(zhì)是它是函數(shù)作用域,但又不隨每次進(jìn)入函數(shù)體而被初始化。由于Javascript中函數(shù)本身也是一種對(duì)象,因此可以這樣:

  1. function foo() {
  2. foo.counter = foo.counter || 0; // 將計(jì)數(shù)器初始化為0
  3. foo.counter++;
  4.  
  5. console.log(foo.counter);
  6. }
  7.  
  8. for (var i = 0; i <=5; i++){
  9. foo();
  10. }

運(yùn)行結(jié)果為輸出1~6個(gè)數(shù)字。如果是匿名函數(shù)的話,可以用arguments.callee來代替函數(shù)名:

  1. function foo() {
  2. arguments.callee.counter = arguments.callee.counter || 0; // 將計(jì)數(shù)器初始化為0
  3. arguments.callee.counter++;
  4.  
  5. console.log(arguments.callee.counter);
  6. }
  7.  
  8. for (var i = 0; i <=5; i++){
  9. foo();
  10. }

this變量

在函數(shù)(不包括構(gòu)造函數(shù))中使用this變量,this的值需要等到函數(shù)調(diào)用時(shí),由其上下文環(huán)境確定。

在構(gòu)造函數(shù)中使用this,其結(jié)果是引用到由構(gòu)造函數(shù)通過new生成的那個(gè)對(duì)象上。

在字面量對(duì)象中定義的函數(shù),this引用到字面量生成的對(duì)象上。

  1. var my = {
  2. init : function(){
  3. console.log(this);
  4. if (typeof this._done_ != 'undefined'){
  5. console.log("already inited.");
  6. }else{
  7. console.log("not inited.");
  8. this._done_ = true;
  9. }
  10. }
  11. }
  12. my.init();
  13. my.init();

第一次運(yùn)行my.init()的結(jié)果顯示“not inited”,但第二次運(yùn)行的結(jié)果就是”already inited.”。同時(shí),結(jié)果顯示this為一個(gè)Object,而非Window。因此,只要在字面量對(duì)象內(nèi)聲明的函數(shù),this都會(huì)始終綁定到當(dāng)前的字面量對(duì)象上,無論是在:{}還是在其中的函數(shù)聲明中。但要注意,this無法傳遞。即如果將this傳遞給一個(gè)函數(shù)作為參數(shù),則在函數(shù)內(nèi)部訪問到的this,并不一定是傳入的this值。

但是,值得注意的是,在字面量對(duì)象的屬性表達(dá)式中使用this,此時(shí)this并非引用到字面量對(duì)象,而是當(dāng)前定義字面量的作用域?qū)ο笊?。比如?/p>

  1. var my = {
  2. mem : "hello",
  3. msg : this.mem + " world!"
  4. };
  5. console.log(my.msg);

上例會(huì)顯示’undefined world’。這是因?yàn)閠his引用到window對(duì)象上,而當(dāng)前window對(duì)象中并無mem這一屬性。
在眾多的Javascript編程書籍中,沒有一本提到上面的例子,這不能不說是個(gè)遺憾。使用字面量對(duì)象來構(gòu)建程序中的單例對(duì)象是一種較普通的設(shè)計(jì)模式,在定義某些變量時(shí),不可避免地要用到其它變量。比如在定義環(huán)境配置時(shí),常常會(huì)先定義一個(gè)home,再定義一些相對(duì)于該home的path。但是這里沒有捷徑可走。下面的定義都會(huì)引起運(yùn)行時(shí)錯(cuò)誤:

  1. var my= {
  2. home : "http://home",
  3. jsdir: my.home + "/js",
  4. init : function(){
  5. console.log("init");
  6. },
  7.  
  8. start : function(){
  9. console.log("start");
  10. my.init();
  11. }
  12. };
  13.  
  14. my.start();

錯(cuò)誤的原因可能是因?yàn)?,上述語句作為一個(gè)詞句執(zhí)行,因此當(dāng)為jsDir/imgDir賦值時(shí),對(duì)象my還沒有創(chuàng)建起來,因此還不能引用my.home。而使用this之所以錯(cuò)誤的原因,則已經(jīng)在前面講過了。然而,如果去掉第2行,則該代碼可以運(yùn)行,盡管我們看到第8行也引用到了my.init();這是因?yàn)?,?行只是定義,并非執(zhí)行;而第2行時(shí)需要立即對(duì)my.home進(jìn)行求值,所以會(huì)發(fā)現(xiàn)my沒有定義。這是在firebug中看到的行為,是否有某些brower并非如此,待考。

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
每個(gè)前端開發(fā)者必會(huì)的 20 個(gè) JavaScript 面試題 – 碼農(nóng)網(wǎng)
前端基礎(chǔ)進(jìn)階(四):詳細(xì)圖解作用域鏈與閉包
一道前端經(jīng)常忽視的JavaScript面試題
javascript 作用域和 this 關(guān)鍵字
看完離編寫高性能的JavaScript又近了一步
Javascript作用域和變量提升
更多類似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服