被以下问题郁闷了下。下面比较抽象简述下这个问题。
index.html文件
Test
test.js文件:
/**
* 定义一个无类型的对象listInfo
*/
var listInfo =
{
// 属性info,为对象类型
info : {
name : "ljlwill"
},
// 方法getName
getName : function()
{
// 我这个例子这样来设置setName,好像“蛮干”哈,现在我只是简化和抽象,实际项目就是要用这些规则
Ajax.call(this.setName);
alert(this.info["name"]);
},
// 方法setName
setName: function(name)
{
this.info["name"] = name; // 大家注意这个this
}
}
/**
* 定义无类型的Ajax对象
*/
var Ajax =
{
// 创建XMLHttpRequest对象
createXMLHttpRequest : function()
{
var xhr;
if (window.ActiveXObject)
{
var versions = ['Microsoft.XMLHTTP', 'MSXML6.XMLHTTP', 'MSXML5.XMLHTTP', 'MSXML4.XMLHTTP', 'MSXML3.XMLHTTP', 'MSXML2.XMLHTTP', 'MSXML.XMLHTTP'];
for (var i=0; i< versions.length; i++)
{
try
{
xhr = new ActiveXObject(versions(i));
break;
}
catch(ex)
{
continue;
}
}
}
else
{
xhr = new XMLHttpRequest();
}
return xhr;
},
// call方法
call : function(callback)
{
var xhr = this.createXMLHttpRequest();
// 以下也一切从简
xhr.open("GET", "index.php", true); //异步
xhr.onreadysatechange = function()
{
// 完成
if (xhr.readySate == 4)
{
swith (xhr.status)
{
case : 200 // OK
if (typeof(callback) == "function")
{
callback.call(this, "ljlwill -- from Ajax"); // 将自身绑定到另外一个对象执行
}
}
xhr = null; // 销毁
}
}
if (xhr != null) xhr.send(null);
}
}
这时,我本意要,点击那个Test链接,先弹出“ljlwill",然后在点击一次的时候是弹出“ljlwill -- from Ajax",可是却不论如何点击,都是弹出"ljlwill"。listInfo对象的setName没有执行?里面加个alert,证明是有执行的。
其实,是这个call方法”捣鬼“。
在JavaScript中,将函数自绑定到另外一个对象上执行,有appliy和call方法,它们只是在参数方面有所不同(具体可相关资料,这里不详述)。
Function.prototype.call(thisArg, [arg1, [arg2, ] ...]),所有函数的内部this指针都会指向thisArg,从以上代码中这个thisArg为Ajax对象,非listInfo对象,这样当然改变不了name值了!
所以,把那callback.call(this, "ljlwill -- from Ajax")该为callback.call(listInfo, "ljlwill -- from Ajax"),问题解决。只是这样有一定的隐患,比如listInfo未定义,或改名,牵动的东西还蛮多!所以,可以就让Ajax对象来运行这函数,而函数的方法内部指明关联哪个对象!
以上也是个人愚见,不是有否不足,或不对,期待讨论~