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);
});