activeExecutionContext = { // Variable object. VO: {...}, this: thisValue };
函数中this值的动态特性
// Global scope // The implicit property of // the global object foo1 = "abc"; alert(foo1); // abc // The explicit property of // the global object this.foo2 = "def"; alert(foo2); // def // The implicit property of // the global object var foo3 = "ijk"; alert(foo3); // ijk
说起JavaScript里面的函数,这个this可不是跟别的语言那样老老实实不变的!实际上,这玩意儿是看执行时的环境怎么说才算数的。所以,在你的函数跑起来之后,this的值可能会变得让人捉摸不透!看看下面这个小例子就能明白。
this值由调用者决定
// Defines foo object. var foo = { name: "Foo" }; // Defines person object. var person = { name: "JK_Rush", say: function() { alert(this === person); alert("My name is " + this.name); } }; person.say(); // My name is JK_Rush // foo and person object refer to // the same function say foo.say = person.say; foo.say(); // My name is Foo.
找函数玩儿得注意,它可能会把”this”当自家的。所以别以为”this”就是某一函数专属的,它可会随着叫它的对象走动!
动态修改this值
你是不是好奇,我究竟能不能在函数中玩弄那个神奇的this呀?告诉你,这可是行不通滴,因为在函数启动之前,this的值早就被固定住了,咱们无法乱来。就算强行改变方法中的this值,最后还是会弹出错误提示的!
// Defines foo object. var foo = { name: "Foo" }; // Defines person object. var person = { name: "JK_Rush", say: function() { alert(this === person); this = foo; // ReferenceError alert("My name is " + this.name); } }; person.say(); // My name is JK_Rush
this值受调用表达式形式影响
说到这个this值,用得好就是个神器,用不好就可能变成空的NULL,甚至变成全局对象。比如说你刚才说的那个函数,要是在调用时左侧没有引用,那它就会变成空字符串NULL,真是让人捉摸不透
// Reference type. var valueOfReferenceType = { base: mybase, propertyName : 'mybasepropertyName' };
特殊情况分析
// Declares varible. var foo = 23; // Declares a function function say() { // Your code. }
哎呦,稀奇古怪事儿总是会出现!比如说,要是你的函数里头,某一边儿有个能指代其它玩意儿的引用型变量,然后给整没了,那可不就等于全局对象了么?尤其是那”背后”的老家伙还健在的话。
// Reference type. var fooReference = { base: global, propertyName: 'foo' }; var sayReference = { base: global, propertyName: 'say' };
with语句与this指向
// Invokes the say method. foo.say(); foo['say']();
很郁闷,当你把某个函数包裹在with里之后,如果这个函数里还有其他属性,那么你就得小心了,因为它们可能会覆盖掉原本的基础对象。这下子麻烦就来了,当你再想使用这些变量的时候,恐怕只能看到修改过的基础对象了。
// Reference type. var fooSayReference = { base: foo, propertyName: 'say' };
构造函数中的this
你刚刚new出的对象是怎么来的?这可是构造函数在背后默默地帮忙。新对象一创建好,就跑到了[[Call]]那边了,接下来在Foo()中把this指向它就大功告成。
// Reference type. var sayReference = { base: global, propertyName: 'say' };
apply()和call()方法应用
这个小窍门就是教大家如何利用这两种方法随时随地改变函数中的`this`值,还能随意添加你想要的参数。`apply()`就像个管家,只负责把第二个参数当做一堆东西来处理;而`call()`就像个潇洒的侠客,不管有多少参数,只要用逗号分开,它都能搞定。
// Declares anonymous function (function () { alert(this); // null => global })();
this与括号左侧引用类型关系
咱们来试试看,如果把引用型变量的值放进左括号里,你知道会怎么样吗?这个时候,`this`就变成了那个值的基类原来那个引用型变量的值,就会消失不见,变成全局对象。
// Declares object. var foo = { bar: function () { alert(this); } }; (foo.bar)(); // foo. (foo.bar = foo.bar)(); // global? (false || foo.bar)(); // global? (foo.bar, foo.bar)(); // global
——————-
在读这个JavaScriptthis值怎么变来变去的文章时,可得留心,这可不是闹着玩儿的。敲起代码来,千万要搞懂每个this到底代表啥,否则犯错就得怪自己了。对新手来说,理解好JavaScript的this指代可是重要得很!
评论0