我正在创建一个对象
var testobj=function(x)
{
var b,c;
var a=x;
var init=function(d,e,f)
{
a=d;
b=e;
c=f;
};
return{
init:init,
b:function(){
return b;
},
a:a,
c:c
}
};
//here some test of the object
var instobj=new testobj(4);
instobj.init(1,2,3);
alert(instobj.a); //display 4
alert(instobj.b()); //display 2
alert(instobj.c); //display nothing
我不明白为什么我无法获得“c'通过简单地引用它,相反,我需要使用函数来返回该值。
答案 0 :(得分:4)
发生什么事了?
我希望你在使用new时使用函数对象,但是你返回了一个对象。
-->return{
init:init,
b:function(){
return b;
},
a:a,
c:c
}
通常在返回对象时不使用new。发生这种情况时,函数对象的上下文会丢失,因此,这就是返回对象的init函数的样子
function(d,e,f)
{
a=d;
b=e;
c=f;
};
字面上没有任何其他内容的引用。此时,您处于全局范围(除非使用了绑定,这是一个不同的问题),导致a,b和c现在全局定义(假设未使用strict)。这样做的目的是创建3个全局变量,然后将它们分配给值。
结果,这就是最终在你的电话中发生的事情。
首先,将三个全局变量a,b和c分配给1,2和3
instobj.init(1,2,3);
接下来,您将警告仍然返回的对象引用的a的值,并从构造函数中获取值4.结果4被警告
alert(instobj.a); //display 4 (because that came from the constructor)
在以下行中,您引用了一个没有上下文的函数,因此引用了全局作用域。它返回的变量是全局变量b
,在上面用init设置为2
alert(instobj.b()); //display 2 (this returned b, a global variable)
最后一个电话是c。但是,c仍然引用原始函数对象的变量c,并且只声明了一次但从未分配给它。 (记住吗?var b,c;
。如果这是var a,c=-1;
,则以下代码会提示-1)。
alert(instobj.c); //display nothing (undefined from var b,c;)
可以改变什么?
通常在javascript中采用原型方法。这意味着您需要设置构造函数,定义每个实例将使用的一些原型函数,然后再创建新的实例。对于你的testobj,看起来像这样:
function Test(x){
this.a = x;
this.b = undefined;
this.c = undefined;
}
Test.prototype.init = function(d,e,f){
this.a = d;
this.b = e;
this.c = f;
};
使用new时,this
引用函数对象的实例。稍后,在引用实例化分配给的变量时,.
属性名称可用于引用this.
属性值。
当使用new时,附加到原型的函数也包含在实例化对象中。它们的范围与上面描述的this
相同,并且属性引用也是相同的。
因此,您可以像这样访问您的测试对象:
var testobj = new Test(4);
testobj.init(1,2,3);
alert(testobj.a);//1
alert(testobj.b);//2
alert(testobj.c);//3
<强> jsFiddle Demo
强>
<子> Link to top of answer 子>
答案 1 :(得分:1)
当您为对象生成属性时,应使用this
,例如:
function TestObj () {
this.c = 3;
this.b = function (number) {
alert(number);
};
return this;
}
var instance = new TestObj();
alert(instance.c);
instance.b(4);
详细了解OOP in JS