被以下问题郁闷了下。下面比较抽象简述下这个问题。
index.html文件
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对象来运行这函数,而函数的方法内部指明关联哪个对象!
以上也是个人愚见,不是有否不足,或不对,期待讨论~