我深入了解了这种特殊行为,我认为我找到了一个很好的解释。
在我了解你为什么不能化名之前文档.getElementById
,我将尝试解释JavaScript函数/对象是如何工作的。
每当调用JavaScript函数时,JavaScript解释器都会确定一个范围并将其传递给函数。
考虑以下功能:
函数和(a,b){返回a+b;}总和(10,20);//返回30;
此函数在Window范围内声明,当您调用它时这
在sum函数中是全局窗口
对象。
对于“sum”函数,“this”的值是多少并不重要,因为它没有使用它。
考虑以下功能:
功能人员(生日){this.birthDate=出生日期;this.getAge=函数(){return new Date().getFullYear()-this.birthDate.getFull Year(();};}var dave=新人员(新日期(1909年1月1日));dave.getAge()//返回100。
当您调用dave.getAge函数时,JavaScript解释器会看到您正在调用戴夫
对象,因此它设置这
到戴维
并调用getAge(获取年龄)
功能。获取代理()
将正确返回100
.
您可能知道,在JavaScript中,可以使用应用
方法。让我们试试看。
var dave=新人员(新日期(1909年1月1日))//2009年100岁var bob=新人员(新日期(1809,1,1))//2009年200岁dave.getAge.apply(鲍勃)//返回200。
在上面的行中,不是让JavaScript决定范围,而是手动将范围作为鲍勃
对象。getAge(获取年龄)
现在将返回200
即使你“以为”你打过电话getAge(获取年龄)
上戴夫
对象。
以上这些有什么意义?函数“松散”地附加到JavaScript对象。例如,你可以
var dave=新人员(新日期(1909年1月1日));var bob=新人员(新日期(1809,1,1));bob.getAge=函数(){return-1;};bob.getAge()//返回-1dave.getAge()//返回100
让我们迈出下一步。
var dave=新人员(新日期(1909年1月1日));var ageMethod=dave.getAge;dave.getAge()//返回100;ageMethod()//回报?????
age方法
执行时抛出错误!怎么搞的?
如果你仔细阅读我的上述观点,你会注意到dave.get年龄
方法是用调用的戴夫
作为这
对象,而JavaScript无法确定的“范围”age方法
执行。所以它将全局“Window”传递为“this”。现在作为窗口
没有出生日期
属性,age方法
执行将失败。
如何解决这个问题?很简单,
ageMethod.apply(戴夫)//返回100。
以上所有内容都有意义吗?如果是这样,那么您将能够解释为什么不能使用别名文档.getElementById
:
var$=document.getElementById;$(“omeElement”);
$
用调用窗口
作为这
如果按Id获取元素
期望实现这
成为文件
,它将失败。
再次解决这个问题,你可以
$.apply(文件,[“omeElement”]);
那么为什么它在Internet Explorer中工作呢?
我不知道按Id获取元素
在IE中,但在jQuery源中有注释(inArray(阵列中)
方法实现)表示,在IE中,窗口==文档
。如果是这样,则使用别名文档.getElementById
应该在IE工作。
为了进一步说明这一点,我创建了一个详细的示例。看看人
下面的函数。
功能人员(生日){var self=此;this.birthDate=出生日期;this.getAge=函数(){//让我们确保调用了getAge方法//使用从Person函数构造的对象。if(this.constructor==个人)return new Date().getFullYear()-this.birthDate.getFulYear(();其他的返回-1;};//getAge函数的智能版本,它将始终引用对象//它是用创建的。this.getAgeSmarter=函数(){return self.getAge();};//getAge函数的最智能版本。//它将尝试使用最合适的范围。this.getAgeSmartest=函数(){var scope=this.constructor==个人?这:自我;return scope.getAge();};}
对于人
上面的函数,下面是各种getAge(获取年龄)
方法将起作用。
让我们使用创建两个对象人
功能。
var yogi=新人员(新日期(1909年1月1日))//年龄为100岁var anotherYogi=新人员(新日期(1809,1,1))//年龄为200岁
console.log(yogi.getAge())//输出:100。
直接来说,getAge方法得到瑜伽士
对象为这
和输出100
.
var ageAlias=yogi.getAge;console.log(ageAlias())//输出:-1
JavaScript interpreter集合窗口
对象为这
和我们的getAge(获取年龄)
方法将返回-1
.
console.log(ageAlias.apply(瑜伽))//输出:100
如果我们设置了正确的范围,您可以使用age别名
方法。
console.log(ageAlias.apply(anotherYogi))//输出:200
如果我们传入其他人对象,它仍将正确计算年龄。
var ageSmarterAlias=yogi.getAgeSmarter;console.log(ageSmarterAlias())//输出:100
这个年龄更智能
函数捕获了原始这
对象,所以现在您不必担心提供正确的范围。
console.log(ageSmarterAlias.apply(anotherYogi))//输出:100!!!
问题在于年龄更智能
就是你永远不能将范围设置为其他对象。
var ageSmartestAlias=yogi.getAgeSmartest;console.log(ageSmartestAlias())//输出:100console.log(ageSmartestAlias.apply(文档))//输出:100
这个年龄最聪明
如果提供的范围无效,函数将使用原始范围。
console.log(ageSmartestAlias.apply(另一个瑜伽))//输出:200
你仍然可以通过另一个人
反对获取AgeSmartest
. :)