JavaScript中arguments和this对象用法分析(2)

function Person(name) { this.name = name; this.setName = function(name) { this.name = name; } } var person1 = new Person("Alice"); var person2 = {"name": "Bruce"}; alert("person1: " + person1.name); // person1: Alice person1.setName("David"); alert("person1: " + person1.name); // person1: David alert("person2: " + person2.name); // person2: Bruce person1.setName.apply(person2, ["Cindy"]); alert("person2: " + person2.name); // person2: Cindy

apply()将person1的方法应用到person2上,this也被绑定到person2上。

3、this优先级

(1)函数是否在new中调用,是的话this绑定到新创建的对象。

(2)函数是否通过call、apply调用,是的话this绑定到指定对象。

(3)函数是否在某个上下文对象中调用,是的话this绑定到该上下文对象。

(4)若都不是,使用默认绑定,若在严格模式下,绑定到undefined,否则绑定到全局对象。

4、this丢失的问题

eg1:

var person = { name: "Alice", getName: function() { return this.name; } }; alert(person.getName()); // Alice var getName = person.getName; alert(getName()); // undefined

当调用person.getName()时,getName()方法是作为person对象的属性被调用的,因此this指向person对象;

当用另一个变量getName来引用person.getName,并调用getName()时,是作为普通函数被调用,因此this指向全局window。

eg2:

<div>正确的方式</div> <script> var getId = function(id) { return document.getElementById(id); }; alert(getId('div').innerText); </script> <div>错误的方式</div> <script> var getId = document.getElementById; alert(getId('div').innerText); // 抛出异常 </script>

问题:第一段调用正常,但第二段调用会抛出异常。

原因:许多引擎的document.getElementById()方法的内部实现中需要用到this,this本来期望指向的是document,当第一段代码在getElementById()方法作为document对象的属性被调用时,方法内部的this确实是指向document的,而第二段代码中,用getId来引用document.getElementById之后,再调用getId,此时就成了普通函数调用,函数内部的this指向了window,而不是原来的document。

解决:利用apply把document当作this传入getId函数,修正this。

<div>修正的方式</div> <script> document.getElementById = (function(func) { return function() { return func.apply(document, arguments); }; })(document.getElementById); var getId = document.getElementById; alert(getId('div').innerText); // 抛出异常 </script>

更多关于JavaScript相关内容感兴趣的读者可查看本站专题:《javascript面向对象入门教程》、《JavaScript常用函数技巧汇总》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/3c3c2c5739a06b2e21f6b6e53befb132.html