对于我遇到的这个问题,我真的找不到一个清晰简洁的答案 - 我甚至不确定如何说出来。但是我正在使用Javascript(一个“类”,如果你愿意的话)构建一个我可以重用的对象。我正在使用JSON方法来处理对象,因为这是我目前熟悉的唯一方法(我知道其他方法,我只是无法坐下来尝试它们)。 / p>
所以,这是我正在做的一个例子:
var Thing = {
'property':{
'one':5,
'two':3
},
'action':(function(arg1, arg2){
alert(arg1 + ' ' + arg2);
return this.property.one + this.property.two;
});
}
var t = Thing;
alert(t.action('x', 'y'));
正如你所看到的,我有了我的对象,并且它有一些嵌套属性。还有一个函数,它应该能够操纵所述属性。
我遇到的问题是范围。我想找到一种方法来引用函数中的对象属性,而不是假定属性属于该函数,因为它们没有。我在过去做过,我刚刚将“this”作为参数传递给函数,一切正常,但我愿意打赌这不是好习惯。另外,正如您所看到的,此函数无论如何都已经有了一些参数。运行此代码会出现错误:“Uncaught TypeError:无法读取未定义的属性'one'。
我想保留构建此对象的方法 - 这是工作的东西,对象已经非常大了;但是我正在寻找的是“回到树上”以获得这些属性。
答案 0 :(得分:2)
您正在此处直接初始化对象。您正在使用的JSON称为object literal。顾名思义,它实际上是字面上的定义对象。
现在让我们来解决你的问题。
当您声明具有this.property.one
的函数时,this
关键字将在通话时解析。它通常是浏览器上的窗口对象。 Read on more this
。所以永远不会指向你的Thing
。您可以做的是为类定义一个函数并将函数添加到其原型中。这是在js中实现oop的经典方式。
function Thing(){
this.property = {one: 5, two: 3}
}
Thing.prototype.action = function(arg1, arg2){
alert(arg1 + ' ' + arg2);
return this.property.one + this.property.two;
}
答案 1 :(得分:1)
这有效:
var Thing = {
'property':{
'one':5,
'two':3
},
'action':(function(arg1, arg2){
alert(arg1 + ' ' + arg2);
return this.property.one + this.property.two;
}) // here don't put a ';'
}
var t = Thing;
alert(t.action('x', 'y'));
答案 2 :(得分:0)
你应该定义一个函数。
var Thing = function(){
this.property = {"one":5, "two":3};
this.action = function(arg1, arg2){/*....*/}
}
var y = new Thing();
alert(y.action("x","y"));
这就是我写课的方式。
正如另一个答案所说,看起来你有;
不应该
答案 3 :(得分:0)
我有两个答案,一个使用您当前的JSON模型,另一个使用更多Javascript方式。
:一种。强>
如此定义 Thing 。
var Thing = {
'property':{
'one':5,
'two':3
},
'action':(function(arg1, arg2){
alert(arg1 + ' ' + arg2);
return this.property.one + this.property.two;
})
}
您创建了一个文字,这意味着每次执行
等代码var t = Thing;
您通过引用传递,不要在内存中创建新对象。因此,使用多个引用Thing的变量会产生问题。
此外,您的问题还会形成这样一个事实:关键字 this 是在运行时找到的,除非由 bind 命令指定,否则通常会引用浏览器窗口。请记住,它必须始终是一个对象。文字的本质是这样的,它不会以外行的方式改变这个变量。
<强>乙强>
现在以更好的方式解决这个问题。可以像其他任何函数一样创建可实例化的对象或类。但是,它们由关键字 new 实例化。为了使用它们自己的引用, this 关键字表示当前范围中派生程度最大的可实例化类。因此,你的例子写得更好
var Thing = function(){
this.property = {};
this.property.one = 5;
this.property.two = 3;
this.action = function Action(arg1, arg2){
alert(arg1 + ' ' + arg2);
return this.property.one + this.property.two;
}
}
var t = new Thing();
alert(t.action('x', 'y'));
我希望有所帮助。
<强>此外强>
你说
我正在寻找的是“回到树上”
虽然我不太清楚你的意思,但我推断如果我到目前为止所说的内容没有帮助,你的意思是你在物体内有物体。例如,假设您有一个也包含Schedule类的Student类。您可能希望从计划类中访问学生数据。虽然这个例子很糟糕,因为按设计,Schedule实例不需要访问Student数据,如果需要,它应该通过函数参数传递,你也可以解决这个问题。
function Student(age){
this.age = age;
this.schedule = new Schedule(this);
}
function Schedule(parent){
this.getAge = function(){return parent.age;}
}
var s = new Student(16);
s.schedule.getAge();
您可以简单地将父对象传递给子对象的实例并完成,按照您的说法备份树。
答案 4 :(得分:0)
如果您需要一个生成不同对象的“类”,那么我认为您应该查看shiplu.mokadd.im的答案。但是,你可能需要一个模块,有点像单身:
var thing = (function() {
var property = {
one:5,
two:3
};
function action(arg1, arg2){
alert(arg1 + ' ' + arg2);
return property.one + property.two;
}
return {
action: action
};
})();
alert(thing.action('x', 'y'));
这里发生了什么:使用所谓的IIFE - 立即调用的函数表达式。它在这里做什么它分配给thing
var无论IIFE返回什么(immidiately) - 所以在这种情况下它返回一个具有action
函数的对象。
为什么这有用?它在IIFE中创建了一个范围,它封装了你要做的任何事情thing
。它还会创建“私有”函数和变量 - 您只需return
所需的内容 - 例如。 var property
在thing
之外不可见,您无法获得对thing.property
的引用。
希望这有用!