5

私は、JavaScript オブジェクトを可能な限り「正しい」ものにしながら、可能な限り直感的に構築できるかどうかを試してきました。Crockford の JSLint.com でさまざまなシナリオを実行してきましたが、うまくいきませんでした。1 つのエラーを修正したようですが、変更により別のエラーが表示されます。以下は、私が得ることができるのとほぼ同じです。誰かがこれについて別の見方をしていますか?

これは、オブジェクトを構造化する典型的な方法です。

function gizmo(id) {

  /* private variables */

  var myId = id;

  /* private methods */

  var init = function () {
    if (myId < 1) {
      setId(1);
    }
  };

  var setId = function (newId) {
    myId = newId;
  };

  // run 'constructor'
  init();

  /* public methods */

  return {
    getId: function () {
      return myId;
    },
    setId: function (newId) {
      setId(newId);
    },
    incrementId: function (inc) {
      setId(myId + inc);
    }
  };
}

// creating an instance of gizmo

var myGizmo = gizmo(-2);
console.log(myGizmo.getId()); // outputs 1

myGizmo.setId(5);
console.log(myGizmo.getId()); // outputs 5

myGizmo.incrementId(2);
console.log(myGizmo.getId()); /// outputs 7

これはうまくいくようです。しかし、これを JSLint で実行すると、2 つのプライベート関数が「暗黙のグローバル」であるというエラーが表示されます。

私が思い付くことができる最善の方法は、次のような変数を使用して関数を上部に宣言することです。

function gizmo(id) {

  /* private variables */

  var myId = id,
      init,
      setId;

  /* private methods */

  init = function () {
    if (myId < 1) {
      setId(1);
    }
  };

  setId = function (newId) {
    myId = newId;
  };

  // run 'constructor'
  init();

  /* public methods */

  return {
    getId: function () {
      return myId;
    },
    setId: function (newId) {
      setId(newId);
    },
    incrementId: function (inc) {
      setId(myId + inc);
    }
  };
}
4

4 に答える 4

3

JSLint は、init で参照される前に setId が定義されていることを想定しています。

これは JSLint を渡します。

function gizmo(id) {

  /* private variables */

  var myId = id;

  /* private methods */

  var setId = function (newId) {
    myId = newId;
  };

  var init = function () {
    if (myId < 1) {
      setId(1);
    }
  };

  // run 'constructor'
  init();

  /* public methods */

  return {
    getId: function () {
      return myId;
    },
    setId: function (newId) {
      setId(newId);
    },
    incrementId: function (inc) {
      setId(myId + inc);
    }
  };
}
于 2010-07-10T04:37:10.060 に答える
1

JSLintのバグだと確信しています。まだ見たことがないsetIdので、グローバルであると想定しています。しかし実際には、 ECMAScript 5 10.5varに従って、すべてが吊り上げられているため、違いはありません。これは、最初の例と2番目の例が意味的に同じであることを意味します。関数内の任意の場所にあるローカル変数宣言はすぐに処理され、バインディングは最初に値を持つように設定されます。ただし、関数(initなど)が実際に実行されるまでに、閉じた値はなくなります。undefinedundefined

これsetIdが最初は未定義であるが、グローバルを参照していないことを確認するには、次のテストを実行します。

function setId()
{
  alert("Global setId");
}
function f()
{
  var init = function()
  {
    setId();
  }
  alert(typeof(setId));
  init();
  var setId = function()
  {

  }
}

未定義を警告し、TypeErrorエラーをスローします。

于 2010-07-10T04:51:43.943 に答える
0

JSlint についてはわかりませんが、「javascript の良い部分」を読んだ後は、常にオブジェクトをリテラルとして宣言しています。

例えば:

Mogwai={
  has_crazy_thoughts:True,
  reacts_to_water:True,
  name: 'Gizmo',
  eat:function(food){
    // code
  },
  become_gremlin:function(){
    // code
  },
  cause_havoc:function(){
    // code
  }
}

上記のオブジェクトを実際に宣言していません。ただの機能。Javascript には内部関数は実際には存在しません。Java とはまったく異なります。

編集: 上記の本 (所属なし) を強くお勧めします: http://oreilly.com/catalog/9780596517748 ... JSlint をもたらした Douglas Crockford によって書かれました。

于 2010-07-10T04:26:55.280 に答える
0

JavaScript を真剣にプログラミングするようになってから長い年月 (数年) が経過したため、ベスト プラクティスの詳細についての記憶はかなり失われています。私が行ったことは、情報に基づいた決定を下すのに役立ついくつかのリソースを掘り下げたことです。

まず、オブジェクトを作成する方法はModule Patternを非常に連想させます。私が思い出す限り、私がリンクした記事はそれについてのかなり良い読み物です. 次に、別の方法でオブジェクトをインスタンス化することをお勧めします。その記事では、少し異なる見方をしています。

于 2010-07-10T04:39:29.773 に答える