实例函数变量没有改变?

时间:2016-02-19 04:23:11

标签: javascript

我尝试在函数运行后控制变量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

3 个答案:

答案 0 :(得分: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>
&#13;
&#13;
&#13;

答案 1 :(得分:3)

这很有效。你可以不使用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
   

答案 2 :(得分:3)

要清楚地了解this声明,您必须明白它代表当前&#34;范围&#34;在函数内部。

宣布:

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

this表示Test函数的当前范围。这就是为什么,当您执行var test = new Test();时,您将能够使用test.clientData,然后访问您在对象初始化中设置的数据。

现在,在clientData对象的test属性中,您有setUserName(我建议您将其命名为setFullName),这又是一个函数({ {3}})。因此,如果我们查看您的代码:

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; 
        }
    };
}

所以诀窍是将this存储在顶层的变量中,因为JavaScript是函数作用域的,变量将可用于作用域内的每个函数。所以现在我们可以做到:

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

我建议您以不同的方式分割数据和方法。现在,您将所有内容放在clientData对象中,这会为您的应用添加一些复杂性。您可以分隔存储的值(名称,年龄,任何存储信息)以及将与数据交互的方法。

我建议这样的事情:

&#13;
&#13;
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
&#13;
&#13;
&#13;

通过这种方式,您可以更轻松地读取代码,并且可以更轻松地执行代码。之后,您可以按照自己的方式组织和设计对象逻辑。

希望它有所帮助。