Javascript 对象创建期间的“this”上下文
我正在尝试这样做:Javascript 对象创建期间的“this”上下文,javascript,object,scope,closures,this,Javascript,Object,Scope,Closures,This,我正在尝试这样做: var test = { a: 10, b: 20, c: (this.a+this.b) }; function myobj(a,b) { this.a = a; this.b = b; this.c = this.a + this.b; } var test = new myobj(10,20); 但它不起作用。如何从test.c中访问test.a? 有可能吗?在对象文本中不可能,因为不能使其引用尚未创建的对象。最好的选择是在单独
var test = {
a: 10,
b: 20,
c: (this.a+this.b)
};
function myobj(a,b) {
this.a = a;
this.b = b;
this.c = this.a + this.b;
}
var test = new myobj(10,20);
但它不起作用。如何从test.c中访问test.a?
有可能吗?在对象文本中不可能,因为不能使其引用尚未创建的对象。最好的选择是在单独的步骤中指定c属性:
var test = {
a: 10,
b: 20
};
test.c = test.a + test.b;
在一个对象文本中是不可能的,因为它不能引用一个尚未创建的对象。最好的选择是在单独的步骤中指定c属性:
var test = {
a: 10,
b: 20
};
test.c = test.a + test.b;
在声明对象文字时不能这样做,最接近的方法是:
var test = {
a: 10,
b: 20
};
test.c = test.a + test.b;
在您的上下文中,这指的是您所处的任何父上下文,而不是测试对象……即使它这样做了,您也不能像这样声明成员,例如,这也是无效的:
var test = { a: 10, b: 20, test.c: test.a + test.b };
…因为test、a和b尚未定义,因为它是一个尚未完成的语句。在声明对象文字时,您不能这样做,您可以做的最接近的操作是:
var test = {
a: 10,
b: 20
};
test.c = test.a + test.b;
在您的上下文中,这指的是您所处的任何父上下文,而不是测试对象……即使它这样做了,您也不能像这样声明成员,例如,这也是无效的:
var test = { a: 10, b: 20, test.c: test.a + test.b };
…因为test、a和b尚未定义,因为它是一条尚未完成的语句。在指定对象文字的表达式中无法引用它。可以在以下行中执行此操作,也可以使用如下构造函数:
var test = {
a: 10,
b: 20,
c: (this.a+this.b)
};
function myobj(a,b) {
this.a = a;
this.b = b;
this.c = this.a + this.b;
}
var test = new myobj(10,20);
对于哪个方法更快,使用对象构造函数创建的速度更快。下面是一个简单的测试用例比较
结果表明,使用构造函数创建对象的速度几乎是使用对象文字创建对象的速度的两倍:
0.450s:testObjectLiteral
0.506s:testObjectLiteralWithFunction
0.280s:testConstructor
以下是内联的测试代码:
// timer function
function time(scope){
time.scope = time.scope || {};
if(time.scope[scope]) {
var duration = (new Date()).getTime()-time.scope[scope];
time.scope[scope] = null;
var results = document.getElementById("results");
results.innerHTML = results.innerHTML + '<p>'+(duration/1000).toFixed(3)+'s : '+scope+'</p>';
} else {
time.scope[scope] = (new Date()).getTime();
}
}
// object creation function with constructor
function myobj(a,b) {
this.a = a;
this.b = b;
this.c = this.a + this.b;
}
function testConstructor(iterations) {
var objs = new Array(iterations);
for(i=0;i<iterations;i++) {
objs[i] = new myobj(i,i+1);
}
return objs;
}
function testObjectLiteralWithFunction(iterations) {
var objs = new Array(iterations);
for(i=0;i<iterations;i++) {
objs[i] = {
a: i,
b: i+1,
c: function() {
return this.a + this.b;
}
};
}
return objs;
}
function testObjectLiteral(iterations) {
var objs = new Array(iterations);
for(i=0;i<iterations;i++) {
var item = {
a: i,
b: i+1
};
item.c = item.a + item.b;
objs[i] = item;
}
return objs;
}
var ITERATIONS = 1000000;
time("testObjectLiteral");
testObjectLiteral(ITERATIONS);
time("testObjectLiteral");
time("testObjectLiteralWithFunction");
testObjectLiteralWithFunction(ITERATIONS);
time("testObjectLiteralWithFunction");
time("testConstructor");
testConstructor(ITERATIONS);
time("testConstructor");
不可能在指定对象文字的表达式中引用它。可以在以下行中执行此操作,也可以使用如下构造函数:
var test = {
a: 10,
b: 20,
c: (this.a+this.b)
};
function myobj(a,b) {
this.a = a;
this.b = b;
this.c = this.a + this.b;
}
var test = new myobj(10,20);
对于哪个方法更快,使用对象构造函数创建的速度更快。下面是一个简单的测试用例比较
结果表明,使用构造函数创建对象的速度几乎是使用对象文字创建对象的速度的两倍:
0.450s:testObjectLiteral
0.506s:testObjectLiteralWithFunction
0.280s:testConstructor
以下是内联的测试代码:
// timer function
function time(scope){
time.scope = time.scope || {};
if(time.scope[scope]) {
var duration = (new Date()).getTime()-time.scope[scope];
time.scope[scope] = null;
var results = document.getElementById("results");
results.innerHTML = results.innerHTML + '<p>'+(duration/1000).toFixed(3)+'s : '+scope+'</p>';
} else {
time.scope[scope] = (new Date()).getTime();
}
}
// object creation function with constructor
function myobj(a,b) {
this.a = a;
this.b = b;
this.c = this.a + this.b;
}
function testConstructor(iterations) {
var objs = new Array(iterations);
for(i=0;i<iterations;i++) {
objs[i] = new myobj(i,i+1);
}
return objs;
}
function testObjectLiteralWithFunction(iterations) {
var objs = new Array(iterations);
for(i=0;i<iterations;i++) {
objs[i] = {
a: i,
b: i+1,
c: function() {
return this.a + this.b;
}
};
}
return objs;
}
function testObjectLiteral(iterations) {
var objs = new Array(iterations);
for(i=0;i<iterations;i++) {
var item = {
a: i,
b: i+1
};
item.c = item.a + item.b;
objs[i] = item;
}
return objs;
}
var ITERATIONS = 1000000;
time("testObjectLiteral");
testObjectLiteral(ITERATIONS);
time("testObjectLiteral");
time("testObjectLiteralWithFunction");
testObjectLiteralWithFunction(ITERATIONS);
time("testObjectLiteralWithFunction");
time("testConstructor");
testConstructor(ITERATIONS);
time("testConstructor");
为什么不将c设为一个函数,以便它总是返回a+b的当前值
var test = {
a: 5,
b: 1,
c: function() {
return this.a + this.b;
}
}
为什么不让c成为一个函数,让它总是返回a+b的当前值呢
var test = {
a: 5,
b: 1,
c: function() {
return this.a + this.b;
}
}
谢谢你的帮助。另一个问题:这种声明对象的方式是否比var myObj={a:4,b:5….}更快;一个?@dizzy_fingers看到我添加到回答中的性能测试用例了谢谢你的帮助。另一个问题:这种声明对象的方式是否比var myObj={a:4,b:5….}更快;一个?@dizzy_fingers看到我在回答中添加的性能测试用例了吗谢谢你的建议。但是性能问题呢?在c:声明之后添加闭包是额外的开销吗?我想是这样的——每次调用c时,它都在计算a+b,而不是简单地检索变量的值。然而,根据你的处境,这种差异可能可以忽略不计。如果您正在执行的加法操作涉及大量值,和/或您多次引用c,则最好在初始化时只进行一次计算,在这种情况下,下面的mbrevoort解决方案可能更有用。归根结底,这取决于您的情况以及a/b在执行过程中是否会发生变化。谢谢您的建议。但是性能问题呢?在c:声明之后添加闭包是额外的开销吗?我想是这样的——每次调用c时,它都在计算a+b,而不是简单地检索变量的值。然而,根据你的处境,这种差异可能可以忽略不计。如果您正在执行的加法操作涉及大量值,和/或您多次引用c,则最好在初始化时只进行一次计算,在这种情况下,下面的mbrevoort解决方案可能更有用。归根结底,这取决于您的情况以及a/b在执行过程中是否会发生变化。