JavaScript中的靜態變量



Answers

您可能會利用JS功能也是對像這一事實 - 這意味著它們可以具有屬性。

例如,引用Javascript中的靜態變量 (現在已消失)文章中給出的示例:

function countMyself() {
    // Check to see if the counter has been initialized
    if ( typeof countMyself.counter == 'undefined' ) {
        // It has not... perform the initialization
        countMyself.counter = 0;
    }

    // Do something stupid to indicate the value
    alert(++countMyself.counter);
}

如果您多次調用該函數,您會看到計數器正在增加。

這可能比使用全局變量對全局名稱空間進行分配更好。


這裡有另一種可能的解決方案,基於閉包: 在javascript中使用靜態變量的技巧

var uniqueID = (function() {
   var id = 0; // This is the private persistent value
   // The outer function returns a nested function that has access
   // to the persistent value.  It is this nested function we're storing
   // in the variable uniqueID above.
   return function() { return id++; };  // Return and increment
})(); // Invoke the outer function after defining it.

這會得到相同的結果 - 除了這次,遞增的值將返回,而不是顯示。

Question

我如何在Javascript中創建靜態變量?




I didn't see this idea in any of the answers so just adding it to the list. If it's a duplicate just let me know and i'll delete it and upvote the other.

I created a sort of super global in my website. Since I have several js files that are loaded on every page load and dozens of other js files that are only loaded on some pages I put all of the "global" function into a single global variable.

At the top of my first included "global" files is the declaration

var cgf = {}; // Custom global functions.

Then I delcare several global helper functions

cgf.formBehaviors = function()
{
    // My form behaviors that get attached in every page load.
}

Then if I need a static variable I just store it outside scope such as outside the document ready or outside the behavior attachment. (I use jquery but it should work in javascript)

cgf.first = true;
$.on('click', '.my-button', function()
{
    // Don't allow the user to press the submit twice.
    if (cgf.first)
    {
        // first time behavior. such as submit
    }
    cgf.first = false;
}

This of course is a global not a static but as it is reinitialized on every page load it accomplishes the same purpose.




以下示例和解釋來自Nicholas Zakas的專業JavaScript for Web Developers第2版。 這是我正在尋找的答案,所以我認為在這裡添加它會有幫助。

(function () {
    var name = '';
    Person = function (value) {
        name = value;
    };
    Person.prototype.getName = function () {
        return name;
    };
    Person.prototype.setName = function (value) {
        name = value;
    };
}());
var person1 = new Person('Nate');
console.log(person1.getName()); // Nate
person1.setName('James');
console.log(person1.getName()); // James
person1.name = 'Mark';
console.log(person1.name); // Mark
console.log(person1.getName()); // James
var person2 = new Person('Danielle');
console.log(person1.getName()); // Danielle
console.log(person2.getName()); // Danielle

此示例中的Person構造函數可以訪問私有變量名稱, getName()setName()方法也是如此。 使用這種模式,名稱變量變為靜態,並將在所有實例中使用。 這意味著在一個實例上調用setName()會影響所有其他實例。 調用setName()或創建新的Person實例將name變量設置為新值。 這會導致所有實例返回相同的值。




還有另一種方法,在瀏覽此線程後解決了我的需求。 這取決於你想用“靜態變量”實現的目標。

全局屬性sessionStorage或localStorage允許數據在會話的整個生命週期中存儲,或者在明確清除之前無限期地存儲數據。 這允許數據在你的頁面/應用的所有窗口,框架,標籤面板,彈出窗口等之間共享,並且比一個代碼段中的簡單“靜態/全局變量”更強大。

它避免了頂級全局變量(如Window.myglobal)的範圍,生命週期,語義,動態等問題。 不知道它有多高效,但對於數量適中的數據並不重要,可以適度的速度訪問。

輕鬆訪問“sessionStorage.mydata =任何東西”並以相似方式檢索。 參見“JavaScript:權威指南,第六版”,David Flanagan,ISBN:978-0-596-80552-4,第20章,第20.1節。 這很容易通過簡單的搜索或者O'Reilly Safaribooks訂閱以PDF形式下載(相當於黃金的重量)。

乾杯,格雷格E




如果你想在你的應用程序中聲明用於創建常量的靜態變量,那麼我發現以下是最簡單的方法

ColorConstants = (function()
{
    var obj = {};
    obj.RED = 'red';
    obj.GREEN = 'green';
    obj.BLUE = 'blue';
    obj.ALL = [obj.RED, obj.GREEN, obj.BLUE];
    return obj;
})();

//Example usage.
var redColor = ColorConstants.RED;



There are 4 ways to emulate function-local static variables in Javascript.

Method 1: Using function object properties (supported in old browsers)

function someFunc1(){
    if( !('staticVar' in someFunc1) )
        someFunc1.staticVar = 0 ;
    alert(++someFunc1.staticVar) ;
}

someFunc1() ; //prints 1
someFunc1() ; //prints 2
someFunc1() ; //prints 3

Method 2: Using a closure, variant 1 (supported in old browsers)

var someFunc2 = (function(){
    var staticVar = 0 ;
    return function(){
        alert(++staticVar) ;
    }
})()

someFunc2() ; //prints 1
someFunc2() ; //prints 2
someFunc2() ; //prints 3

Method 3: Using a closure, variant 2 (also supported in old browsers)

var someFunc3 ;
with({staticVar:0})
    var someFunc3 = function(){
        alert(++staticVar) ;
    }

someFunc3() ; //prints 1
someFunc3() ; //prints 2
someFunc3() ; //prints 3

Method 4: Using a closure, variant 3 (requires support for EcmaScript 2015)

{
    let staticVar = 0 ;
    function someFunc4(){
        alert(++staticVar) ;
    }
}

someFunc4() ; //prints 1
someFunc4() ; //prints 2
someFunc4() ; //prints 3



您可以在JavaScript中創建一個靜態變量,如下所示。 這裡count是靜態變量。

var Person = function(name) {
  this.name = name;
  // first time Person.count is undefined, so it is initialized with 1
  // next time the function is called, the value of count is incremented by 1
  Person.count = Person.count ? Person.count + 1 : 1;
}

var p1 = new Person('User p1');
console.log(p1.constructor.count);   // prints 1
var p2 = new Person('User p2');
console.log(p2.constructor.count);   // prints 2

您可以使用Person函數或任何實例將值分配給靜態變量:

// set static variable using instance of Person
p1.constructor.count = 10;         // this change is seen in all the instances of Person
console.log(p2.constructor.count); // prints 10

// set static variable using Person
Person.count = 20;
console.log(p1.constructor.count); // prints 20



關於ECMAScript 2015推出的class 。其他答案並不完全清楚。

這裡有一個例子展示瞭如何用ClassName創建一個靜態的var staticVarvar synthax:

class MyClass {
    constructor(val) {
        this.instanceVar = val;
        MyClass.staticVar = 10;
    }
}

var class1 = new MyClass(1);
console.log(class1.instanceVar);      // 1
console.log(class1.constructor.staticVar); // 10

// New instance of MyClass with another value
var class2 = new MyClass(3);
console.log(class1.instanceVar);      // 1
console.log(class2.instanceVar);      // 3

要訪問靜態變量,我們使用.constructor屬性,該屬性返回對創建該類的對象構造函數的引用。 我們可以在兩個創建的實例上調用它:

MyClass.staticVar = 11;
console.log(class1.constructor.staticVar); // 11
console.log(class2.constructor.staticVar); // 11 <-- yes it's static! :)

MyClass.staticVar = 12;
console.log(class1.constructor.staticVar); // 12
console.log(class2.constructor.staticVar); // 12



你可以使用arguments.callee來存儲“靜態”變量(這在匿名函數中也是有用的):

function () {
  arguments.callee.myStaticVar = arguments.callee.myStaticVar || 1;
  arguments.callee.myStaticVar++;
  alert(arguments.callee.myStaticVar);
}



我已經看到了幾個類似的答案,但是我想提一下這篇文章最好描述,所以我想和你分享一下。

這裡有一些代碼取自它,我修改了這些代碼以獲得一個完整的示例,希望可以為社區帶來好處,因為它可以用作類的設計模板。

它也回答你的問題:

function Podcast() {

    // private variables
    var _somePrivateVariable = 123;

    // object properties (read/write)
    this.title = 'Astronomy Cast';
    this.description = 'A fact-based journey through the galaxy.';
    this.link = 'http://www.astronomycast.com';

    // for read access to _somePrivateVariable via immutableProp 
    this.immutableProp = function() {
        return _somePrivateVariable;
    }

    // object function
    this.toString = function() {
       return 'Title: ' + this.title;
    }
};

// static property
Podcast.FILE_EXTENSION = 'mp3';
// static function
Podcast.download = function(podcast) {
    console.log('Downloading ' + podcast + ' ...');
};

考慮到這個例子,你可以像下面這樣訪問靜態屬性/函數

// access static properties/functions
Podcast.FILE_EXTENSION;                // 'mp3'
Podcast.download('Astronomy cast');    // 'Downloading Astronomy cast ...'

對象的屬性/功能簡單如下:

// access object properties/functions
var podcast = new Podcast();
podcast.title = 'The Simpsons';
console.log(podcast.toString());       // Title: The Simpsons
console.log(podcast.immutableProp());  // 123

請注意 ,在podcast.immutableProp()中,我們有一個closure對_somePrivateVariable的引用保留在函數內部。

你甚至可以定義getter和setter 。 看看這個代碼片段(其中d是要為其聲明屬性的對象的原型, y是在構造函數外不可見的私有變量):

// getters and setters
var d = Date.prototype;
Object.defineProperty(d, "year", {
    get: function() {return this.getFullYear() },
    set: function(y) { this.setFullYear(y) }
});

它通過getset函數定義屬性d.year - 如果你沒有指定set ,那麼屬性是只讀的,不能被修改(注意如果你設置它,你不會得到一個錯誤,但它沒有效果)。 每個屬性都有屬性writablewritable configurable (允許在聲明後更改)和enumerable (允許將其用作枚舉器),這些屬性默認為false 。 你可以在第三個參數中通過defineProperty來設置它們,例如enumerable: true

這個語法也是有效的:

// getters and setters - alternative syntax
var obj = { a: 7, 
            get b() {return this.a + 1;}, 
            set c(x) {this.a = x / 2}
        };

它定義了一個可讀/可寫屬性a ,一個只讀屬性b和一個只寫屬性c ,通過它可以訪問屬性a

用法:

console.log(obj.a); console.log(obj.b); // output: 7, 8
obj.c=40;
console.log(obj.a); console.log(obj.b); // output: 20, 21

筆記:

為避免您忘記new關鍵字時的意外行為,我建議您將以下內容添加到函數Podcast

// instantiation helper
function Podcast() {
    if(false === (this instanceof Podcast)) {
        return new Podcast();
    }
// [... same as above ...]
};

現在,以下兩個實例都將按預期工作:

var podcast = new Podcast(); // normal usage, still allowed
var podcast = Podcast();     // you can omit the new keyword because of the helper

'new'語句創建一個新對象並複制所有屬性和方法,即

var a=new Podcast();
var b=new Podcast();
a.title="a"; b.title="An "+b.title;
console.log(a.title); // "a"
console.log(b.title); // "An Astronomy Cast"

還要注意的是,在某些情況下,在構造函數Podcast使用return語句可以返回一個自定義對象,該類保護內部依賴的類但需要暴露的對象。 這在文章系列的第2章(對象)中有進一步的解釋。

你可以說abPodcast繼承。 現在,如果你想添加一個方法到Podcast,適用於所有這些在ab被實例化後? 在這種情況下,按如下所示使用.prototype

Podcast.prototype.titleAndLink = function() {
    return this.title + " [" + this.link + "]";
};

現在再次調用ab

console.log(a.titleAndLink()); // "a [http://www.astronomycast.com]"
console.log(b.titleAndLink()); // "An Astronomy Cast [http://www.astronomycast.com]"

你可以here找到關於原型的更多細節。 如果你想做更多的繼承,我建議看看this 。

我上面提到的文章系列 強烈推薦閱讀,它們還包括以下主題:

  1. 功能
  2. 對象
  3. 原型
  4. 強化構造函數的新功能
  5. 吊裝
  6. 自動分號插入
  7. 靜態屬性和方法

請注意 ,JavaScript中的自動分號插入 “功能”(如6.中所述)通常是導致代碼中出現奇怪問題的原因。 因此,我寧願將它視為一個錯誤而不是一個功能。

如果你想閱讀更多, here有一篇非常有趣的關於這些主題的MSDN文章 ,其中一些內容提供了更多的細節。

有趣的閱讀內容 (也包括上面提到的主題)是來自MDN JavaScript指南的那些文章:

如果你想知道如何在JavaScript中模擬c# out參數 (如DateTime.TryParse(str, out result) ),你可以在這裡找到示例代碼。

那些正在使用IE瀏覽器的人 (除非您使用F12打開開發人員工具並打開控制台選項卡,否則無法使用JavaScript控制台)可能會發現以下代碼段很有用。 它允許你使用console.log(msg); 如以上示例中所使用的。 只需將它插入Podcast功能。

為了您的方便,以下是一個完整的單一代碼片段中的代碼:

let console = { log: function(msg) {  
  let canvas = document.getElementById("log"), br = canvas.innerHTML==="" ? "" : "<br/>";
  canvas.innerHTML += (br + (msg || "").toString());
}};

console.log('For details, see the explaining text');

function Podcast() {

  // with this, you can instantiate without new (see description in text)
  if (false === (this instanceof Podcast)) {
    return new Podcast();
  }

  // private variables
  var _somePrivateVariable = 123;

  // object properties
  this.title = 'Astronomy Cast';
  this.description = 'A fact-based journey through the galaxy.';
  this.link = 'http://www.astronomycast.com';

  this.immutableProp = function() {
    return _somePrivateVariable;
  }

  // object function
  this.toString = function() {
    return 'Title: ' + this.title;
  }
};

// static property
Podcast.FILE_EXTENSION = 'mp3';
// static function
Podcast.download = function(podcast) {
  console.log('Downloading ' + podcast + ' ...');
};


// access static properties/functions
Podcast.FILE_EXTENSION; // 'mp3'
Podcast.download('Astronomy cast'); // 'Downloading Astronomy cast ...'

// access object properties/functions
var podcast = new Podcast();
podcast.title = 'The Simpsons';
console.log(podcast.toString()); // Title: The Simpsons
console.log(podcast.immutableProp()); // 123

// getters and setters
var d = Date.prototype;
Object.defineProperty(d, "year", {
  get: function() {
    return this.getFullYear()
  },
  set: function(y) {
    this.setFullYear(y)
  }
});

// getters and setters - alternative syntax
var obj = {
  a: 7,
  get b() {
    return this.a + 1;
  },
  set c(x) {
    this.a = x / 2
  }
};

// usage:
console.log(obj.a); console.log(obj.b); // output: 7, 8
obj.c=40;
console.log(obj.a); console.log(obj.b); // output: 20, 21

var a=new Podcast();
var b=new Podcast();
a.title="a"; b.title="An "+b.title;
console.log(a.title); // "a"
console.log(b.title); // "An Astronomy Cast"

Podcast.prototype.titleAndLink = function() {
    return this.title + " [" + this.link + "]";
};
    
console.log(a.titleAndLink()); // "a [http://www.astronomycast.com]"
console.log(b.titleAndLink()); // "An Astronomy Cast [http://www.astronomycast.com]"
<div id="log"></div>

筆記:

  • 一些關於JavaScript編程的一些很好的提示,提示和建議,你可以在這裡找到(JavaScript最佳實踐)那裡('var'與'let') 。 還推薦這篇關於隱式類型轉換(強制)的文章

  • 使用類並將它們編譯為JavaScript的便捷方式是TypeScript。 這裡有一個遊樂場 ,您可以在這裡找到一些示例,向您展示它的工作原理 即使您目前沒有使用TypeScript,您也可以查看一下,因為您可以在並排視圖中將TypeScript與JavaScript結果進行比較。 大多數例子都很簡單,但也有一個可以立即嘗試的光線跟踪器例子。 我建議特別通過在組合框中選擇它們來查看“使用類”,“使用繼承”和“使用泛型”示例 - 這些都是您可以立即在JavaScript中使用的很好的模板。




There is no such thing as an static variable in Javascript. This language is prototype-based object orientated, so there are no classes, but prototypes from where objects "copy" themselves.

You may simulate them with global variables or with prototyping (adding a property to the prototype):

function circle(){
}
circle.prototype.pi=3.14159



試試這個:

如果我們定義一個屬性並覆蓋它的getter和setter來使用Function Object屬性,那麼理論上你可以在JavaScript中有一個靜態變量

例如:

function Animal() {
    if (isNaN(this.totalAnimalCount)) {
        this.totalAnimalCount = 0;
    }
    this.totalAnimalCount++;
};
Object.defineProperty(Animal.prototype, 'totalAnimalCount', {
    get: function() {
        return Animal['totalAnimalCount'];
    },
   set: function(val) {
       Animal['totalAnimalCount'] = val;
   }
});
var cat = new Animal(); 
console.log(cat.totalAnimalCount); //Will produce 1
var dog = new Animal();
console.log(cat.totalAnimalCount); //Will produce 2 and so on.




函數的/類只允許單個構造函數的對象範圍。 Function Hoisting, declarations & expressions

  • 使用Function構造函數創建的函數不會創建對其創建上下文的閉包; 他們總是在全球範圍內創建。

      var functionClass = function ( ) {
            var currentClass = Shape;
            _inherits(currentClass, superClass);
            function functionClass() { superClass.call(this); // Linking with SuperClass Constructor.
                // Instance Variables list.
                this.id = id;   return this;
            }
        }(SuperClass)
    

Closures - 關閉的副本功能與保存的數據。

  • 每個閉包的副本被創建為一個具有自己的自由值或引用的函數,每當在另一個函數中使用函數時,都會使用閉包。
  • JavaScript中的閉包就像通過innerFunctions維護其父函數的所有局部變量的副本。

      function closureFun( args ) {
            // Local variable that ends up within closure
            var num = args;
            num++;
            return function() { console.log(num); }
        }
        var closure1 = closureFun( 5 );
        var closure2 = closureFun( 777 );
        closure1(); // 5
        closure2(); // 777
        closure2(); // 778
        closure1(); // 6
    

ES5函數類 :使用Object.defineProperty(O,P,Attributes)

Object.defineProperty()方法直接在對像上定義新屬性,或者修改對像上的現有屬性,並返回該對象。

通過使用``創建了一些方法,這樣每一次都可以輕鬆理解函數類。

'use strict';
var Shape = function ( superClass ) {
    var currentClass = Shape;
    _inherits(currentClass, superClass); // Prototype Chain - Extends

    function Shape(id) { superClass.call(this); // Linking with SuperClass Constructor.
        // Instance Variables list.
        this.id = id;   return this;
    }
    var staticVariablesJOSN = { "parent_S_V" : 777 };
    staticVariable( currentClass, staticVariablesJOSN );

    // Setters, Getters, instanceMethods. [{}, {}];
    var instanceFunctions = [
        {
            key: 'uniqueID',
            get: function get() { return this.id; },
            set: function set(changeVal) { this.id = changeVal; }
        }
    ];
    instanceMethods( currentClass, instanceFunctions );

    return currentClass;
}(Object);

var Rectangle = function ( superClass ) {
    var currentClass = Rectangle;

    _inherits(currentClass, superClass); // Prototype Chain - Extends

    function Rectangle(id, width, height) { superClass.call(this, id); // Linking with SuperClass Constructor.

        this.width = width;
        this.height = height;   return this;
    }

    var staticVariablesJOSN = { "_staticVar" : 77777 };
    staticVariable( currentClass, staticVariablesJOSN );

    var staticFunctions = [
        {
            key: 'println',
            value: function println() { console.log('Static Method'); }
        }
    ];
    staticMethods(currentClass, staticFunctions);

    var instanceFunctions = [
        {
            key: 'setStaticVar',
            value: function setStaticVar(staticVal) {
                currentClass.parent_S_V = staticVal;
                console.log('SET Instance Method Parent Class Static Value : ', currentClass.parent_S_V);
            }
        }, {
            key: 'getStaticVar',
            value: function getStaticVar() {
                console.log('GET Instance Method Parent Class Static Value : ', currentClass.parent_S_V);
                return currentClass.parent_S_V;
            }
        }, {
            key: 'area',
            get: function get() {
                console.log('Area : ', this.width * this.height);
                return this.width * this.height;
                }
        }, {
            key: 'globalValue',
            get: function get() {
                console.log('GET ID : ', currentClass._staticVar);
                return currentClass._staticVar;
            },
            set: function set(value) {
                currentClass._staticVar = value;
                console.log('SET ID : ', currentClass._staticVar);
            }
        }
    ];
    instanceMethods( currentClass, instanceFunctions );

    return currentClass;
}(Shape);

// ===== ES5 Class Conversion Supported Functions =====
function defineProperties(target, props) {
    console.log(target, ' : ', props);
    for (var i = 0; i < props.length; i++) {
        var descriptor = props[i];
        descriptor.enumerable = descriptor.enumerable || false;
        descriptor.configurable = true;
        if ("value" in descriptor) descriptor.writable = true;
        Object.defineProperty(target, descriptor.key, descriptor);
    }
}
function staticMethods( currentClass, staticProps ) {
    defineProperties(currentClass, staticProps);
};
function instanceMethods( currentClass, protoProps ) {
    defineProperties(currentClass.prototype, protoProps);
};
function staticVariable( currentClass, staticVariales ) {
    // Get Key Set and get its corresponding value.
    // currentClass.key = value;
    for( var prop in staticVariales ) {
        console.log('Keys : Values');
        if( staticVariales.hasOwnProperty( prop ) ) {
            console.log(prop, ' : ', staticVariales[ prop ] );
            currentClass[ prop ] = staticVariales[ prop ];
        }
    }
};
function _inherits(subClass, superClass) {
    console.log( subClass, ' : extends : ', superClass );
    if (typeof superClass !== "function" && superClass !== null) {
        throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
    }
    subClass.prototype = Object.create(superClass && superClass.prototype, 
            { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } });
    if (superClass)
        Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
}

下面的代碼片段是要測試一下每個實例都有自己的實例成員和常用靜態成員副本。

var objTest = new Rectangle('Yash_777', 8, 7);
console.dir(objTest);

var obj1 = new Rectangle('R_1', 50, 20);
Rectangle.println(); // Static Method
console.log( obj1 );    // Rectangle {id: "R_1", width: 50, height: 20}
obj1.area;              // Area :  1000
obj1.globalValue;       // GET ID :  77777
obj1.globalValue = 88;  // SET ID :  88
obj1.globalValue;       // GET ID :  88  

var obj2 = new Rectangle('R_2', 5, 70);
console.log( obj2 );    // Rectangle {id: "R_2", width: 5, height: 70}
obj2.area;              // Area :  350    
obj2.globalValue;       // GET ID :  88
obj2.globalValue = 999; // SET ID :  999
obj2.globalValue;       // GET ID :  999

console.log('Static Variable Actions.');
obj1.globalValue;        // GET ID :  999

console.log('Parent Class Static variables');
obj1.getStaticVar();    // GET Instance Method Parent Class Static Value :  777
obj1.setStaticVar(7);   // SET Instance Method Parent Class Static Value :  7
obj1.getStaticVar();    // GET Instance Method Parent Class Static Value :  7

Static method calls are made directly on the class and are not callable on instances of the class. But you can achieve the calls for static members from inside an instance.

Using syntax:

   this.constructor.staticfunctionName();
class MyClass {
    constructor() {}
    static staticMethod() {
        console.log('Static Method');
    }
}
MyClass.staticVar = 777;

var myInstance = new MyClass();
// calling from instance
myInstance.constructor.staticMethod();
console.log('From Inside Class : ',myInstance.constructor.staticVar);

// calling from class
MyClass.staticMethod();
console.log('Class : ', MyClass.staticVar);

ES6 Classes: ES2015 classes are a simple sugar over the prototype-based OO pattern. Having a single convenient declarative form makes class patterns easier to use, and encourages interoperability. Classes support prototype-based inheritance, super calls, instance and static methods and constructors.

Example : refer my previous post.




If you want to use prototype then there is a way

var p = function Person() {
    this.x = 10;
    this.y = 20;
}
p.prototype.counter = 0;
var person1 = new p();
person1.prototype = p.prototype;
console.log(person1.counter);
person1.prototype.counter++;
var person2 = new p();
person2.prototype = p.prototype;
console.log(person2.counter);
console.log(person1.counter);

Doing this you will be able to access the counter variable from any instance and any change in the property will be immediately reflected!!




在JavaScript中,變量默認是靜態的。 示例

var x = 0;

function draw() {
    alert(x); //
    x+=1;
}

setInterval(draw, 1000);

x的值每1000毫秒增加1
它會打印1,2,3等




Related