如何使用新Person(名称,描述)访问变量?

时间:2014-11-18 17:41:47

标签: javascript object

在查看Cookie Clicker源代码时,我注意到了一个奇特的Game对象系统,他使用了新的Game.Building(" cursor" ...)。然后我决定用自己的代码测试这个,所以我用基本的用户变量做了同样的事情。

AI.User = function(username, password) {
    try {
        this.username = username;
        this.password = password;

        this.setUsername = function(username) { this.username = username; };
        this.setPassword = function(password) { this.password = password; };
        this.getUsername = function() { return this.name; };
        this.getPassword = function() { return this.password; };
        this.GetUserByUsername = function(username) { };

        return true;
    }
    catch(err) {
        console.log(err);
        return false;
    }
};
new AI.User("John Smith", "JSmith42");

问题是我不知道如何访问创建的变量。

4 个答案:

答案 0 :(得分:0)

如果你问为什么要创建这样的变量,那是因为它是该变量的构造函数。您可以只调用构造函数并使用传入的值填充正确的参数,而不是创建没有名称或密码的User对象并在以后设置它。

答案 1 :(得分:0)

这是在javascript中使用OO样式的简单方法。

如果您想了解更多内容,可以参考this post

答案 2 :(得分:0)

您需要在变量中捕获new表达式的结果:

var user = new AI.User("John Smith", "JSmith42");
console.log(user.getUsername();); // outputs "John Smith"

请注意,您还可以使用函数的.prototype属性创建一次getter和setter,而不必在每次有人创建新对象时重新创建它们。以下是an article I wrote

的示例
function Person(first, last)
{
    this.first = first;
    this.last = last;
}
var john = new Person("John", "Doe");
var mary = new Person("Mary", "Deer");
Person.prototype.full = function() {return this.first + " " + this.last;};
alert(john.full()); // "John Doe"
  

这里发生了很多事情。

     
      
  1. 我们创建了一个function,在调用时会在其this对象上设置属性。
  2.   
  3. 我们通过在函数调用之前放置new关键字来创建该函数的两个单独实例。这可确保johnmary引用完全独立的对象,每个对象都有自己的firstlast属性。
  4.   
  5. 我们创建了一个新功能,并将其分配到full功能Person媒体资源的prototype媒体资源中。 prototype属性存在于所有函数上,并允许您定义应该存在于从该函数创建的每个对象上的后备属性。
  6.   
  7. 我们在full()上调用john函数。 JavaScript看到john对象实际上没有full函数,因此它会查找Person.prototype.full()函数并调用它。但是,在该调用中,this仍然引用john对象。
  8.   

答案 3 :(得分:0)

JavaScript中的面向对象编程

当你使用new运算符的函数(即作为构造函数)时,它实际上将函数包装在一个额外的代码中以创建一个新对象,它设置为this,并且然后在最后返回该对象。 **因此,要保存调用结果,只需将其分配给变量,例如var myUser = new AI.User("John Smith", "JSmith42");

进入细节,你可以想到它有点像这样。 我要提供的代码与幕后实际发生的代码不完全匹配,但它涵盖了基础知识

function constructObject(constructor) {
    var newPrototype = constructor.prototype || Object.prototype,
        newThis = Object.create(newPrototype),
        constructorResult;

    constructor.apply(
        newThis,
        Array.prototype.slice.call(arguments, 1)
    );
    if (constructorResult !== undefined) {
        return constructorResult;
    }
    return newThis;
}

当你调用“new Constructor(a,b,c)”时,它就像我在这里提到的那样调用“constructObject(constructor,a,b,c)”。

第2行中的“Object.create”创建了一个全新的对象,其原型与我们传入的内容相同。请注意,newPrototype从constructor.prototype中获取,如果不存在则,Object.prototype。然后,这个“newPrototype”对象成为我们传递的对象的原型。

“constructor.apply”然后调用构造函数,将newThis对象设置为this进行该调用,并传入我们可能拥有的任何其他参数但将构造函数移出。我们保存函数的返回值,即使构造函数返回任何内容都是不好的做法。

这是一个问题:如果由于某种原因构造函数返回了一个对象,那么我们将返回该对象而不是我们创建的对象。否则,我们会返回新对象。这是我的代码与实际情况不完全匹配的重点之一,因为引擎有更好的方法来检查返回的内容。

使用new而不将结果保存在变量中并不是一种好习惯。它有效,但看起来很奇怪,我怀疑这是你看到它时感到困惑的部分原因。

Cookie Clicker中的面向对象编程

Cookie Clicker基本上在JavaScript的之上实现了自己的简单“类OO”系统。有三种对象:Game.Object,Game.Upgrade和Game.Achievement。没有继承,原型或其他,但因为它通过一系列回调函数工作,所以仍然存在一种多态性。

new运算符与标准JavaScript 中的运算方式相同。关键是所有三个基本构造函数在每次调用时都会保存对this的引用,在Game对象中的三个列表之一中。 这就是Cookie Clicker如何密切关注它创建的对象而不将它们保存在变量中:它实际上是这样,而不是“在开放式”。最终的结果几乎就像一种表格(除了其他东西,因为游戏对象很大)。

模仿这种风格可能不是一个好主意。它看起来没有其他JavaScript代码,这可能是它为什么如此混淆你的很大一部分原因。 Orteil本人似乎正在远离它:Idle Game Maker(他的后续引擎)的源代码与Cookie Clicker非常相似,但对象系统已经消失。这是一个黑魔法:这是一个有趣的研究JavaScript的深奥细节,但不是你应该实际练习的东西。

考虑到Cookie Clicker的主题,这是完全合适的。