JavaScript中protoypal对象中的值

JavaScript中protoypal对象中的值,javascript,constructor,this,Javascript,Constructor,This,我正在尝试这样的事情: (function() { var Foo, foo; Foo = function(proto) { var obj, privateMethod, publicMethod; privateMethod = function() { return console.log("private", this); }; publicMethod = function() { console.log("publi

我正在尝试这样的事情:

(function() {
  var Foo, foo;

  Foo = function(proto) {
    var obj, privateMethod, publicMethod;
    privateMethod = function() {
      return console.log("private", this);
    };
    publicMethod = function() {
      console.log("public", this);
      return privateMethod();
    };
    obj = Object.create(proto);
    obj.bar = publicMethod;
    return obj;
  };

  foo = new Foo({
    baz: "dooz"
  });

  foo.bar();

}).call(this);
显然,这是调用publicMethod时的对象本身,但在privateMethod中设置为全局对象。我知道这可以通过改变来解决:

      return privateMethod();
致:


我知道当一个函数嵌套在一个函数中时,这个get会丢失,但我没想到会出现这种情况。我是在这里遇到这个JavaScript错误,还是有什么我还不明白的地方?

您正在调用
foo.bar()
。这意味着在
foo
上调用函数
bar()
,这意味着
This
foo
内部
bar()

在您的例子中,
foo
是一个
foo
对象
obj
bar()
publicMethod


publicMethod()
调用
privateMethod()
时,没有上下文,因此
这个
成为全局
这个
窗口
)。

您正在调用
foo.bar()
。这意味着在
foo
上调用函数
bar()
,这意味着
This
foo
内部
bar()

在您的例子中,
foo
是一个
foo
对象
obj
bar()
publicMethod

publicMethod()
调用
privateMethod()
时,没有上下文,因此
this
成为全局
this
window
)。上下文(
this
)在javascript中是由函数调用方式设置的,决不是函数本身的属性

obj.bar = function() { console.log(this) };
obj.bar()    // obj
obj['bar']() // obj

// But break the function off the object, and this changes
fn = obj.bar
fn() // window
这个例子向我们展示的是那里的点语法设置了
this
。想想
obj.bar()
obj.bar.call(obj)
的语法糖

因此,您的公共方法获得了正确的
this
,因为它在外部代码中是如何调用的

foo.bar();
但是调用私有方法时根本没有接收者

return privateMethod();
因此不指定上下文,默认为全局对象


因此,如果您在构造函数中创建这些函数,您就有了一些灵活性

您可以在构造函数中将
this
的正确值指定给其他值,并在私有函数中使用该值。(可能是最好的选择)

或者,如果您的JS目标引擎支持
Function.prototype.bind
(遗憾的是,并非所有都支持),您可以:

privateMethod = function() {
  return console.log("private", this);
}.bind(this);
它将返回具有指定上下文的函数,无论发生什么情况

或者你可以自己手动绑定

_privateMethod = function() {
  return console.log("private", this);
}

Foo = function(proto) {
  privateMethod = function() {
    _privateMethod.call(this);
  }
}
在javascript中,上下文(
)是由函数的调用方式设置的,决不是函数本身的属性

obj.bar = function() { console.log(this) };
obj.bar()    // obj
obj['bar']() // obj

// But break the function off the object, and this changes
fn = obj.bar
fn() // window
这个例子向我们展示的是那里的点语法设置了
this
。想想
obj.bar()
obj.bar.call(obj)
的语法糖

因此,您的公共方法获得了正确的
this
,因为它在外部代码中是如何调用的

foo.bar();
但是调用私有方法时根本没有接收者

return privateMethod();
因此不指定上下文,默认为全局对象


因此,如果您在构造函数中创建这些函数,您就有了一些灵活性

您可以在构造函数中将
this
的正确值指定给其他值,并在私有函数中使用该值。(可能是最好的选择)

或者,如果您的JS目标引擎支持
Function.prototype.bind
(遗憾的是,并非所有都支持),您可以:

privateMethod = function() {
  return console.log("private", this);
}.bind(this);
它将返回具有指定上下文的函数,无论发生什么情况

或者你可以自己手动绑定

_privateMethod = function() {
  return console.log("private", this);
}

Foo = function(proto) {
  privateMethod = function() {
    _privateMethod.call(this);
  }
}

您可能在wtih Object.create中遇到问题,因为并非所有浏览器都支持它。我不确定这能否解释私有函数和公共函数之间的范围差异。即使使用指向公共函数的条显式定义proto对象,作用域也保持不变。这很有趣。另一方面,为什么。当您可以()进行自调用时,调用传递窗口对象的匿名函数?@croteau:为什么。当您可以()进行自调用时,调用传递窗口对象的匿名函数?-因为这引用的是对象本身而不是全局,并且简单地使用()不起作用,因为privateMethod不是对象的属性。由于并非所有浏览器都支持它,因此wtih object.create可能会出现问题。我不确定这是否能解释private和public函数之间的范围差异。即使使用指向公共函数的条显式定义proto对象,作用域也保持不变。这很有趣。另一方面,为什么。当您可以()进行自调用时,调用传递窗口对象的匿名函数?@croteau:为什么。当您可以()进行自调用时,调用传递窗口对象的匿名函数?-因为它引用的是对象本身而不是全局对象,并且简单地使用()是不起作用的,因为privateMethod不是对象的属性。