我正在尝试将此.SOME_MEMBER传递给某个方法,但它不会像同一个成员那样通过。下面的代码应该对我正在尝试的内容有所了解。
function App()
{
this.canvas = new Object();
}
App.prototype.createCanvas = function(obj, width, height)
{
obj = document.createElement('canvas');
obj.setAttribute('width', width);
obj.setAttribute('height', height);
log(obj == this.canvas); //false
log(this.canvas == app.canvas); //true
//it's clear that this refers to app
//so why doesn't obj refers to this.canvas?
//how do i get obj to equal this.canvas?
}
App.prototype.init = function()
{
this.createCanvas(this.canvas, 800, 600);
log(this.canvas.width); //undefined
}
var app = new App();
app.init();
现在,我知道我可以简单地执行以下操作:
function App()
{
this.canvas = new Object();
}
App.prototype.createCanvas = function(width, height)
{
this.canvas = document.createElement('canvas');
this.canvas.setAttribute('width', width);
this.canvas.setAttribute('height', height);
}
App.prototype.init = function()
{
this.createCanvas(800, 600);
log(this.canvas.width); //800
}
var app = new App();
app.init();
这适用于大多数应用程序,但我仅限于将变量命名为this.canvas。我最终需要这种方法更灵活一点。
请记住,我正在使用函数document.createElement和element.setAttribute作为示例;它们可以替换为修改变量obj的任何东西。
所以当“this.canvas”被用作参数时,会发生什么?我将如何实现我的目标?
提前致谢!
答案 0 :(得分:2)
那么为什么obj没有引用this.canvas?
因为你在函数中做的第一件事就是给它一个不同的值:
App.prototype.createCanvas = function(obj, width, height)
{
obj = document.createElement('canvas');
// ^------------------------------------------ here
obj.setAttribute('width', width);
obj.setAttribute('height', height);
log(obj == this.canvas); //false
log(this.canvas == app.canvas); //true
//it's clear that this refers to app
//so why doesn't obj refers to this.canvas?
//how do i get obj to equal this.canvas?
}
JavaScript是一种纯粹的传值语言。 obj
参数包含您传入的值(来自this.canvas
,因为这是您在调用它时所给出的); obj
不是对this.canvas
属性的引用。要按照您想要的方式执行您想要的操作,需要通过引用传递this.canvas
(属性),这是您在JavaScript中无法做到的。 (但见下文。)
现在,我知道我可以简单地执行以下操作:
(代码省略)
这适用于大多数应用程序,但我仅限于将变量命名为
this.canvas
。我最终需要这种方法更灵活一点。
这是一个有点奇怪的要求(当然所有App
个实例都应该有canvas
中的画布),但是如果你想能够告诉createCanvas
要放置的对象上的属性画布上,你可以这样做:
JavaScript支持两种引用对象属性的方法:使用文字(this.canvas
)的虚线表示法,以及使用字符串(this["canvas"]
)的括号表示法。在后一种情况下,字符串不必是文字,它可以是任何探索的结果 - 包括变量引用。
所以你的createCanvas
变为:
App.prototype.createCanvas = function(propName, width, height)
{
// Create the canvas
var obj = document.createElement('canvas');
obj.setAttribute('width', width);
obj.setAttribute('height', height);
// Save that canvas to the given property
this[propName] = obj;
}
你这样称呼它:
App.prototype.init = function()
{
this.createCanvas("canvas", 800, 600);
}
也就是说,让createCanvas
返回画布更直接,因此调用代码可以将它放在任何需要的地方:
App.prototype.createCanvas = function(width, height)
{
// Create the canvas
var obj = document.createElement('canvas');
obj.setAttribute('width', width);
obj.setAttribute('height', height);
return obj;
}
然后
App.prototype.init = function()
{
this.canvas = this.createCanvas(800, 600);
}
旁注:你丢失了分号,当你有x = ...
时,即使;
是函数表达式,它最后也需要..
。例如,App.prototype.init = ...
最后需要;
:
App.prototype.init = function()
{
this.canvas = this.createCanvas(800, 600);
}; // <=== Here
由于恐怖是automatic semicolon insertion,它不会导致语法错误,但我强烈建议不要依赖它,它做错了的边缘情况会在你最不期望的时候咬你它(并且最不能承受)。从长远来看,始终包含正确的分号可以节省时间。
答案 1 :(得分:0)
你的行,
obj = document.createElement('canvas');
覆盖传递给createCanvas
方法的obj变量,并将其完全设置为新对象。变量分配会中断先前的引用,并创建对新对象的新引用。 obj变量是对另一个对象的引用。您无法使用它将引用的对象更改为完全不同的对象。
如果通过调用方法或更改属性来对obj变量进行操作,那些将全部作用于原始对象。因此,可能会将this
对象传递给方法(尽管这似乎有点无意义,除非您计划在不同的范围内调用该函数)。