2

私はこのコードを持っています:

function Person(name){      
    var self = this;

    this.name = name;

    function hello(){
        alert("hello " + self.name);
    }

    return {
        hello: hello
    };
}

var newPerson = new Person("john");

newPerson.hello();

'this'キーワードを使用して、'hello'関数の'name'プロパティにアクセスできるようにしたい。'self'変数を使用する代わりの方法が必要です。

jqueryの$.proxy関数を使用してコンテキストを制御することを除いて、変数'self'を使用せずに同じコードを作成するにはどうすればよいですか?

以下のようなコードが必要ですが、「newPerson.hello()」を呼び出すと、「name」は常に「undefined」になります。関数のスコープは常に呼び出し元のドットの左側にあるオブジェクトであり、この場合、作成時に値「john」が割り当てられているのは「newPerson」であると常に信じていたため、理由はわかりません。オブジェクト。

function Person(name){              
    this.name = name;

    function hello(){
        alert("hello " + this.name);
    }

    return {
        hello: hello
    };
}

var newPerson = new Person("john");

newPerson.hello();

ありがとうございました。

4

4 に答える 4

9

.bind関数の所有者を、渡すオブジェクトに強制するために使用できます。したがって、次のようにPersonオブジェクトを記述できます。

function Person(name){ 
    this.name = name;

    var hello = function(){
        alert("hello " + this.name);
    }.bind(this);

    return {
        hello: hello
    };
}

これにより、それを呼び出している.helloコンテキストで常に実行されるようになります。Person

これがデモです:

---jsFiddleデモ---

于 2012-09-06T13:58:44.413 に答える
5

new関数が返すキーワードを使用する場合、デフォルトではreturnを使用しないでthis ください。関数の宣言方法を変更する必要があります。

これがフィドルです

http://jsfiddle.net/SaintGerbil/9SAhD/

function Person(name){              
    this.name = name;
    this.hello = function (){
        alert("hello " + this.name);
    }
}

var newPerson = new Person("john");

newPerson.hello();​

名前を非公開にする必要がある場合は編集してください。

function Person(name){              
    var _name = name;
    this.hello = function (){
        alert("hello " + _name);
    }
}

var newPerson = new Person("john");

newPerson.hello();​

あなたの質問に答えて、関数を呼び出す4つの方法がありますこれらはthisそれらの価値に影響を与えます

  • コンストラクター呼び出し(newキーワードを使用)ここthisで、は自動的に返される新しいオブジェクトです。
  • 関数がオブジェクトにアタッチされ、そこから呼び出された場合のメソッド呼び出しは、からthis呼び出されたオブジェクトです。
  • 関数を呼び出す関数を直接呼び出すとthis、グローバルオブジェクトになります(newなしでコンストラクターを呼び出す場合のよくある間違い)
  • メソッドを使用してこれを指定する場合は、Apply \ Call呼び出し(例としてjackwandersを参照)

さらに編集

したがって、最初に目的のコードを取得して、何が起こっているのかを説明します。

function Person(name){
    this.name = name; // 1

    function hello(){ // 2
        alert("hello " + this.name); // 3
    } 

    return {
        hello: hello
    }; //4
}

関数としての人は、 2つの方法で呼び出すことができます。

var x = Person("ted");

var x = new Person("jimmy");

大文字でPersonに名前を付けたので、それは人々が使用することを期待していることを意味しますnew
したがって、これに固執して関数を入力すると、javascriptが新しいオブジェクトを作成し、それをに割り当てますthis

  • 1行目では、「name」変数をアタッチthisし、渡されたパラメーターで初期化します。
  • 2行目では、「hello」関数をにアタッチしthisます。
  • 3行目、関数はこれに「name」変数が付加されていることを想定しています(今のところこれはそうです)。
  • 4行this目(デフォルトの動作)ではなく、新しいオブジェクトを宣言し、それに関数をアタッチしています。この新しいオブジェクトには、スコープ内に「name」変数がありません。

したがって、オブジェクトを作成すると、関数がアタッチされたオブジェクトが取得されますが、正しく実行する必要がある変数に到達できません。それがあなたが未定義を取得している理由です。

テキストボックスを展開する必要があるときに、私が困惑していることを常に心配しているのは理にかなっていますか?

または、関数をできるだけ詳細に書き出すと、次のようになります。

function Person(name){
  var this = new Object();
  this.name = name;
  var hello = function (){
    alert("hello " + this.name);
  } 
  this.hello = hello;

  var that = new Object();
  that.hello = hello;

  return that;
}
于 2012-09-06T14:00:28.333 に答える
4

あなたは2つのことを混乱させているようです。

a)通常の機能

function CreatePerson(name) {
    // create a new object
    var person = {};
    // or (if you want to provide a prototype)
    var person = Object.create(...);

    // fill it with some more data
    person.name = name;
    person.foo = 123;
    person.bar = function() { /* ... your method body ... */ }; 
}

これは次のように呼び出されます:

var person = CreatePerson("Jack");

b)コンストラクター

function Person(name) {
    // called after a Person is created,
    // `this` is bound to the new object
    // and its prototype is set to `Person.prototype`

    this.name = name;
    this.foo = 123;
    this.bar = function() { /* ... your method body ... */ }; 
}

var person = new Person("Jack");

ここで特別なnew構文に注意してください。

このスタイルを使用する場合、作成されたすべてのインスタンスに対してではなく、メソッドを1回だけ作成することをお勧めします。

function Person(name) {
    // called after a Person is created,
    // `this` is bound to the new object
    // and its prototype is set to `Person.prototype`

    this.name = name;
    this.foo = 123;
}
Person.prototype.bar = function() {
    /* ... your method body ... */
};

var person = new Person("Jack");
于 2012-09-06T14:08:59.577 に答える
1

このようにすることはうまくいきます。

関数内でこれにアクセスしたいだけの場合は、このようにすることができます。return {hello:hello}を使用して関数を宣言します。必要な場合を除いて、関数を宣言する必要はありません。

例1

       function _persons(array) {
          this.available = array;
          this.write = function () {
              writedata(this.available, '#array2');
          };
          this.SortAge = function () {
              array.sort(compare);
              writedata(this.available, '#array3');
          };
          array.sort(compareName);
      } 
     var users = new _persons(myarray);

例2

  function Person(name ){
       this.name = name ;
        this.hello = function(){
        alert("hello " + this.name);
        }
      }

      var a = "john";
      var newPerson = new Person(a); 
      newPerson.hello(); var
      otherPerson = new Person("annie"); 
      otherPerson.hello();
于 2012-09-06T13:55:02.210 に答える