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”属性;我想要一个替代使用“自我”变量的方法。

除了使用 jquery 的 $.proxy 函数来控制上下文之外,我如何编写相同的代码但没有变量'self'?

我想要一个如下所示的代码,但当我调用“newPerson.hello()”时,“名称”总是“未定义”。我不知道为什么,因为我一直认为函数的范围始终是调用者点左侧的对象,在这种情况下,它是“newPerson”,在创建时被赋值为“john”物体。

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的情况下调用构造函数时的常见错误)
  • 使用方法指定应该是什么时应用\调用调用(以jackwanders为例)

进一步编辑

因此,在开始时获取您想要的代码并解释正在发生的事情。

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

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

    return {
        hello: hello
    }; //4
}

作为函数的 Person可以通过两种方式调用:

var x = Person("ted");

var x = new Person("jimmy");

由于您已将 Person 命名为大写,这意味着您希望人们使用new.
因此,我们输入函数,然后 javascript 创建一个新对象并将其分配给this.

  • 第 1 行,我们将一个“名称”变量附加到this并使用传递的参数进行初始化。
  • 第 2 行我们将一个 'hello' 函数附加到this.
  • 第 3 行,该函数期望有一个“名称”变量存在附加到它(它现在这样做)。
  • 第 4 行,而不是 return this(默认行为),我们现在声明一个新对象并将函数附加到它。这个新对象在其范围内没有“名称”变量。

因此,当您创建对象时,您会得到一个附加了函数的对象,但它无法访问它需要正确执行的变量。这就是为什么你得到未定义的原因。

这有意义吗?当我必须扩展文本框时,我总是担心我在胡扯吗?

或者,如果我尽可能详细地写出你的函数,它会看起来像这样。

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

您似乎混淆了两件事。

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语法。

使用这种风格时,您可能只想创建一次方法,而不是为每个创建的实例创建方法:

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

这样做很有效。

如果您只想在函数中访问 this ,您可以这样做。你使用 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 回答