替代';self=this';在javascript中使用对象

替代';self=this';在javascript中使用对象,javascript,scope,Javascript,Scope,我有以下代码: 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(); 我

我有以下代码:

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”总是“未定义”。我不知道为什么,因为我一直认为函数的作用域总是调用方点左边的对象,在这种情况下,在创建对象时,是“newPerson”被赋值为“john”

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

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

    return {
        hello: hello
    };
}

var newPerson = new Person("john");

newPerson.hello();
谢谢。

这样做很有效

如果您只想访问函数中的this,可以这样做。 您可以使用返回{hello:hello}来声明函数,并且不需要对其执行任何操作,除非它是您想要的

例1

例2


您可以使用
.bind
强制函数的所有者成为您传递的任何对象。因此,您可以这样编写
Person
对象:

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

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

    return {
        hello: hello
    };
}
这将确保
.hello
始终在调用它的
人员的上下文中执行

下面是一个演示:


在使用
new
关键字时,默认情况下不要使用return,函数将返回
您将需要更改函数的声明方式

这是一把小提琴

编辑如果您要求姓名是私人的,那么这里有一个替代方案

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

var newPerson = new Person("john");

newPerson.hello();​
在回答您的问题时,有4种方法可以调用函数 这些会影响
的值

  • 构造函数调用(使用
    new
    关键字),其中
    this
    是自动返回的新对象
  • 方法调用如果函数附加到对象并从中调用,则
    是从中调用的对象
  • 函数调用对函数的直接调用将导致
    this
    成为全局对象(在没有新函数的情况下调用contstructor是一个常见错误)
  • 当使用方法指定应该是什么时,Apply\Call调用(参见jackwanders示例)
进一步编辑

因此,在开始时使用您想要的代码并解释发生了什么

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

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

    return {
        hello: hello
    }; //4
}
可以通过两种方式调用Person函数:

var x=个人(“ted”)

var x=新人(“吉米”)

由于您用大写字母命名Person,这意味着您希望人们使用
new

因此,我们继续输入函数,javascript创建一个新对象并将其分配给
this

  • 第1行,我们将一个“name”变量附加到
    上,并用传递的参数初始化
    
  • 第2行,我们将“hello”函数附加到
  • 第3行函数希望有一个'name'变量连接到此函数(目前它是这样做的)
  • 第4行不是返回此
  • (默认行为),而是声明一个新对象并将函数附加到它。此新对象在其作用域中没有“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;
}

你似乎混淆了两件事

a) 正则函数 这就像:

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;
}
Person.prototype.bar = function() {
    /* ... your method body ... */
};

var person = new Person("Jack");

这似乎不能解决此人的问题。你是不是不小心发错了问题?这就是一个例子。他可以用我的例子来说明这一点。谢谢。阅读您的示例后,我理解的是,当您使用“this”将函数分配给变量时,您强制函数使用对象构造函数上下文中的“this”,并且在调用对象函数后,当对象被构造时,“this”将始终是“this”。我说的对吗?@Samuel写的
Person
是正确的;它被称为“耐用物品”。在他的函数中,
.name
成为构造函数的“私有”。在您的函数中,
.name
是可公开访问的。@Samuel Yes当您使用
new
调用函数时,此
引用正在创建的对象。当您调用对象上的函数时,它会将其作为方法调用,这意味着
将引用该对象。您所做的是声明一个对象并返回另一个对象(其中包含hello函数)。@jackwanders我知道“持久对象”模式,如果您需要将名称变为私有,则将其声明为变量,而不是附加到
@Saint Gerbi非常感谢。我现在了解到,我的原始对象定义了一个函数,当未将该函数分配给具有“this.functionName=…”的对象时,每次调用该函数时,javascript都将返回一个新函数,在本例中,“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;
}
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");
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");
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");