2016-02-19 4 views
6

関数実行後に変数fullNameをコンソールで操作しようとしましたが、値が変更されず、コンソールのデフォルト値Not Set、なぜですか?インスタンス関数の変数は変更されていませんか?

function Test() { 
    this.clientData = { 
     fullName : "Not Set", 
     setUserName: function (firstName, lastName) { 
      this.fullName = firstName + " " + lastName; 
     }, 
     getUserInput2: function (firstName, lastName, callback) { 
      callback(firstName, lastName); 
     } 
    }; 

    this.getUserInput1 = function (firstName, lastName, callback) { 
     callback(firstName, lastName); 
    }; 
} 

var test = new Test(); 

test.getUserInput1("A1", "B1", test.clientData.setUserName); 

console.log("test.clientData.fullName : " + test.clientData.fullName);//Not Set 
//expected => A1 B1 

test.clientData.getUserInput2("A2", "B2", test.clientData.setUserName); 
console.log("test.clientData.fullName : " + test.clientData.fullName);//Not Set 
//expected => A2 B2 
+2

おそらくコールバック関数*の[* 'this']の複製です(http://stackoverflow.com/questions/14561723/this-in-callback-functions)。また、あなたは[* "どのように"この "キーワードの作品は?*](http://stackoverflow.com/questions/3127429/how-does-the-this-keyword-work/3127440#3127440)と[ * MDN:this *](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this)。 – RobG

答えて

2

を使用してmanualyコールバックを設定することができます。 bind()関数を使用せずにこれを行うことができます。 Testオブジェクトを変数に格納するだけです。

function Test() { 
 
var t = this 
 
this.clientData = { 
 
      fullName : "Not Set", 
 
      setUserName: function (firstName, lastName) { 
 
      t.clientData.fullName = firstName + " " + lastName; 
 
      }, 
 
      getUserInput2: function (firstName, lastName, callback) { 
 
       callback(firstName, lastName); 
 
      } 
 
     }; 
 
this.getUserInput1 = function (firstName, lastName, callback) { 
 
    callback(firstName, lastName); 
 
     }; 
 
} 
 

 
var test = new Test(); 
 
test.getUserInput1("A1", "B1", test.clientData.setUserName); 
 
console.log("test.clientData.fullName : " + test.clientData.fullName);//Not Set 
 
//expected => A1 B1 
 
test.clientData.getUserInput2("A2", "B2", test.clientData.setUserName); 
 
console.log("test.clientData.fullName : " + test.clientData.fullName);//Not Set 
 

+0

あなたはそれが 'var t = this;'であると思うと思います – Pevara

+0

間違いを指摘するための@Pevaraありがとう –

3

コールバックが呼び出されたとき、コールバックのコンテキスト(this)値がclientDataオブジェクトではないからです。

あなたはこれが機能しているFunction.bind()

function Test() { 
 
    this.clientData = { 
 
    fullName: "Not Set", 
 
    setUserName: function(firstName, lastName) { 
 
     this.fullName = firstName + " " + lastName; 
 
    }, 
 
    getUserInput2: function(firstName, lastName, callback) { 
 
     callback(firstName, lastName); 
 
    } 
 
    }; 
 
    this.getUserInput1 = function(firstName, lastName, callback) { 
 
    callback(firstName, lastName); 
 
    }; 
 
} 
 

 
var test = new Test(); 
 
var userInput = new test.getUserInput1("A1", "B1", test.clientData.setUserName.bind(test.clientData)); 
 
snippet.log("test.clientData.fullName : " + test.clientData.fullName); //Not Set 
 
//expected => A1 B1 
 
test.clientData.getUserInput2("A2", "B2", test.clientData.setUserName.bind(test.clientData)); 
 
snippet.log("test.clientData.fullName : " + test.clientData.fullName); //Not Set 
 
//expected => A2 B2
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --> 
 
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

+0

'.bind()'について少し説明します。+ 1 – Rayon

+0

関数の* this *は実行コンテキストの1つのパラメータですが、**コンテキストではありません。 OPの問題は、コールバックの* this *が適切な値に設定されていないため、固定する必要がある(バインド、終了、呼び出しを変更する)ことです。 – RobG

3

this声明について明確に理解するために、あなたはそれが関数内で現在の「スコープ」を表していることを理解する必要があります。

あなたが宣言:

function Test() { 
    this.clientData = { 
    .... 
    }; 
} 

thisTest機能の現在のスコープを表します。そのため、var test = new Test();を実行すると、test.clientDataを使用して、オブジェクトの初期化で設定したデータにアクセスできるようになります。

は今、あなたのtestオブジェクトのあなたのclientData財産の内側には、再度機能(JavaScript is function scoped)である(私はそれsetFullNameに名前を付けることをお勧めします)setUserNameを持っています。私たちはあなたのコードを見ればだから:

function Test() { 
    this.clientData = { 
     fullName: "Not Set", 
     setFullName: function(firstName, lastName) { 
      /* 
      * `this` represents the scope of the `setFullName` function, 
      * and not the scope of the `Test` function 
      */ 
      this.fullName = firstName + " " + lastName; 
     } 
    }; 
} 

だから、トリックはJavaScriptが機能スコープですので、トップレベルの変数にthisを格納することで、変数がスコープ内のすべての機能のために利用できるようになります。別の方法であなたのデータとあなたの方法を分割するために、

function Test() { 
    var self = this; 
    self.clientData = { 
     fullName: "Not Set", 
     setFullName: function(firstName, lastName) { 
      self.clientData.fullName = firstName + " " + lastName; 
     } 
    }; 
} 

は、私はあなたをお勧めします。だから今、私たちはそれを行うことができます。今度はあなたのアプリに複雑さを加えるclientDataオブジェクトにすべてを入れます。保存された値(名前、年齢、ストレージ情報)と、データとやりとりするメソッドを分けることができます。

は、私はそのような何かを示唆:

function Person() { 
 
    var self = this; 
 
    self.fullName = "Not Set" 
 
    self.setFullName = function(firstName, lastName) { 
 
     self.fullName = firstName + " " + lastName; 
 
    }; 
 
} 
 
var john = new Person(); 
 
john.setFullName("John", "Doe"); 
 
console.log("john.fullName : " + john.fullName); // Display : John Doe 
 
var bruce = new Person() 
 
bruce.setFullName("Bruce", "Wayne"); 
 
console.log("bruce.fullName : " + bruce.fullName); // Display : Bruce Wayne

あなたが読むためにはるかに簡単にコードと実行するより簡単にコードを持ってこの方法です。その後、あなたが望むようにあなたのオブジェクトロジックを整理し、設計することはあなた次第です。

希望します。

関連する問題