javascript对象

javascript对象,javascript,function,object,reference,this,Javascript,Function,Object,Reference,This,我有一个对象,它有另一个内部对象。如何从内部对象调用父对象 var test = { init: function () { var instance = this; }, call: function() { this.stop(); // works }, stop: function() { this.parseText(); // works }, parseText: {

我有一个对象,它有另一个内部对象。如何从内部对象调用父对象

var test = {
    init: function () {
        var instance = this;
    },
    call: function() {
        this.stop(); // works
    },
    stop: function() {
        this.parseText(); // works
    },
    parseText: {
        load: function ()
        {
            this.call(); //*** dont work
            instance.call(); // work, but what if i have this instance (same name) on another object, would'nt this conflict it?
        }
    }
};

我正在使用一个实例,它可以正常工作,但是如果我或其他人在另一个对象中编写了一个实例(同名)var,它会不会冲突并覆盖此实例?

如果您所担心的只是
测试
更改,请按以下方式操作:

var test = (function() {
    var object = {}
    object.call = function() {
        this.stop(); // works
    };
    object.stop = function() {
        this.parseText(); // apparently works, even though parseText is not a function
    };
    object.parseText = {
        load: function() {
            object.call(); // works
        }
    };
    return object;
})();

如果您不知道
test
的名称,可以使用自调用匿名函数创建包装器,并引用如下所示的对象

请注意,
test
不是对函数的引用,而是对匿名函数返回值的引用由于对象名(
obj
)被包装在函数中,因此无法从外部读取或修改它

下面的解决方案很简洁,不会污染
测试的范围,而且工作起来很有魅力。如前所述,
test
指的是与
obj
相同的对象。但是,不可能从外部操纵变量
obj
,从而使函数内部的代码中断

var test = (function(){ //Self-executing function
    var obj = {
        call: function() {
            this.stop(); // works
        },
        stop: function() {
            this.parseText(); // works
        },
        parseText: {
            load: function ()
            {
                obj.call();  // obj refers to the main object
            }
        }
    };
    return obj; //Return the object, which is assigned to `test`.
})(); //Invoke function
更新 如果不包装对象,就不可能可靠地引用对象内部的
self
this
、或任何对象引用

您当前的解决方案不起作用,请参阅下面代码中的注释:

var obj = {
   init: function(){
      var instance = this; //`instance` is declared using `var` inside a function
   },                       // This variable cannot read from "the outside"
   parseText: {
      load: function(){
          instance.call(); //Does NOT work! instance is not defined
      }
   }
}
“”实际上是函数对象上的一个内置函数,可用于调用指定用于此操作的函数。你的代码是如何工作的?它似乎不应该,因为parseText不是一个函数

也许可以试试这个:

parseText: function() {
    var load =  function ()
    {
        this.call(); //*** should work
    };
    load.call(this);
}
给你一个合理的例子,说明如何做你想做的事,但没有真正说明原因

< JavaScript >代码> > <代码>完全由函数调用(现在,参见下面的细节)来定义,而不是函数定义的地方,它是在一些具有相同关键字的语言中(java、C++、c……)。 您,即编码者,确定每次调用函数时此
将是什么。主要有两种方法:通过对象属性(在同一表达式中)调用函数,或显式使用函数的内置
call
apply
函数

通过对象属性 使用对象属性:

obj.foo();    // or
obj["foo"](); // both work
这做了两件截然不同的事情,但它们协作设置
this
值:首先,通过查找对象
obj
foo
属性来找到函数引用。然后,调用该函数。因为您将其作为检索属性值的同一个整体表达式的一部分调用,所以JavaScript引擎将在调用中将
this
设置为
obj

因此,在您的示例中,
test.parseText.load()
,在
load
调用
中,这个
将是
parseText
,而不是
test
,因为它是查找
load
的对象

请注意,通过属性查找设置-
-仅在同时完成时有效。这不起作用:

这不起作用,因为它们不是同时完成的。属性查找和函数调用是分开的

使用
调用
应用
设置
的第二种方法更为明确:所有函数都有
调用
应用
属性,它们本身就是函数引用,使用您提供的信息调用函数。在这两种情况下,第一个参数都是在调用期间用作this
的对象。因此,如果我们想修复上面的示例,但它不起作用,我们可以这样做:

var f = obj.foo;
f.call(obj);  // `this` will be `obj` within the call
f.apply(obj); // same
call
apply
之间的唯一区别是如何提供函数参数。使用
调用
,可以将它们作为进一步的离散参数提供给函数;使用
apply
,可以传入一个参数数组

所以这些都做了同样的事情:

// 1 - Directly via property
obj.foo("a", "b", "c");

// 2 - Using `call`
f = obj.foo;
f.call(obj, "a", "b", "c");

// 3 - Using `apply`
f = obj.foo;
f.apply(obj, ["a", "b", "c"]); // Note the `[ ... ]`, one array with three elements
您可以看到
call
apply
如何与现有结构协同工作:

test.parseText.load.call(test.parseText);
调用
test.parseText.load
,使
这个
=
test.parseText
在调用中

Eric在回答中所做的是使用一个闭包,使调用
parseText
时使用
this
值变得更简单

进一步阅读(披露:来自我的博客):


我说:

在JavaScript中,
这个
完全由函数的调用方式设置 (目前

我说“现在”的原因是,在ES6中,JavaScript获得了“箭头函数”,与其他函数不同,箭头函数中的
this
的值是由它们的创建位置设置的,而不是它们的调用方式:它们从创建它们的上下文中获得
this

假设您在一个对象方法中编写代码,并希望使用对象的另一个方法(我不知道)从数组中输出信息(是的,这是人为的)。在ES5中,您可能会这样做:

this.output("Entries:");
theArray.forEach(function(entry, index) {
    this.output(index + ": " + entry);
}, this);
// ^------- tells `forEach` what to use as `this` during the callback
如果您停止该参数,您将有一个bug:

this.output("Entries:");
theArray.forEach(function(entry, index) {
    this.output(index + ": " + entry); // <== Bug, `this` is either
                                       // `undefined` (strict) or
                                       // the global object (loose)
});

谢谢你的回答,请再次检查我的问题,我已经编辑过了。不,我不担心。但是我想用$this或self或instance作为名称,但是我担心如果有人再次编写相同的var,我会担心它是否会被忽略?@Basit:no,
对象
不能被覆盖。它是匿名函数的局部变量,所以只能可以在该函数中修改。看起来像是您放置了
return obj;
twice@Eric谢谢,修复了。我从函数的底部开始,移到顶部,无意中重复了底部:p@Basit请看我答案中的黑体字。我想在对象中使用self/this或instance,而不是直接使用对象名..不想在内部使用对象名functions@Basit:你需要研究这些答案(Rob和@Er
this.output("Entries:");
theArray.forEach(function(entry, index) {
    this.output(index + ": " + entry); // <== Bug, `this` is either
                                       // `undefined` (strict) or
                                       // the global object (loose)
});
this.output("Entries:");
theArray.forEach((entry, index) => {
  this.output(index + ": " + entry);
});