JavaScript中this的运用
@(笔记)[JavaScript]
this关键字是JavaScript中最复杂的机制之一。它是一个很特别的关键字,被自动定义在所有函数作用域中。但是即便是经验丰富的JavaScript开发者也很难说清它到底指向什么:
任何足够先进的技术都和魔法无异。 ——Archur C.Clarke
误解
指向自身 :在函数中的this误解为指向函数本身;(每个函数的this是在函数调用时被绑定的,完全取决去函数的调用位置(也就是函数的调用方法,而不是函数声明的位置))
1234567891011121314151617181920var count = 0;function foo(num) {console.log("foo: " + num);//尝试记录foo被调用的次数this.count++;}foo.count = 0;for(var i = 0; i < 5; i++) {foo(i);}console.log(foo.count);//0//如果没有在全局定义声明count并初始化,下面的会输出NaNconsole.log(count);//5/*上面的例子中函数foo中的this并不是指向函数本身,而是指向全局window对象,foo.count = 0为foo函数初始化了count变量,但是this.count的自增是对于全局的count而言的,如果全局没有初始化或者没有声明count的话,console.log(count)得到的结果就是NaN。以上说明this并不是指向函数本身*/它的作用域:误解this指向函数的作用域。(this任何时候都不指向函数作用域,作用域“对象“无法通过
JavaScript代码访问,因为它存在于JavaScript引擎内部。)123456789101112131415function foo() {var a = 2;this.bar();}function bar() {console.log(this.a);}foo();/*foo函数中的this尝试调用全局的bar函数,这个是多余的一步,因为bar函数就在全局中,可以通过作用域链访问到然而bar函数中的this.a是指向全局window的,因为没有声明,所以返回undefined上面的代码企图访问作用域,失败了*/
this的运用
纯粹的函数调用:全局函数的调用,this代表的是全局对象window
123456789101112var foo = function() {console.log(this == window);}foo();//输出true//再次确认调用全局var a = 1;function test() {this.a = 0;}console.log(a);//1test();console.log(a);//调用test()改变全局a之后输出0作为对象的方法调用:作为某个对象的方法调用,this指向这个对象
1234567var obj = {method: function() {console.log(this === obj);//trueconsole.log(this === window)//false}}obj.method();函数内调用内部函数:在函数内部调用函数,不管是在全局函数中调用函数,还是在方法中调用函数,this绑定全局window;也就是说子函数孙函数,只要是以函数的方式调用,this 就铁了心绑定 window 对象了
12345678910111213141516171819202122var foo = function() {console.log(this === window)var method = function() {console.log(this == window)}method();}foo();//两个输出都是true//在某个对象的方法中调用函数var foo = {method: function() {console.log(this === foo);var methods = function() {console.log(window === this);}methods();}}foo.method();//两个都输出true作为构造函数调用:所谓的构造函数,就是通过这个函数生成一个新的对象
123456789101112131415161718function foo(name, age) {this.name = name;this.age = age;}var mewhat = new foo('mewhat','18');console.log(mewhat);//输出foo {name: "mewhat", age: "18"},同时还有一个__proto__原型对象//输出数据:{"name":"mewhat","age":"18"}console.log(JSON.stringify(mewhat));//为了表明this不是全局对象,对代码做了点改变var a = 2;function foo() {this.a = 1;}var test = new foo();console.log(a);//2,全局中的a并没有被改变console.log(test.a);//1apply与call调用:apply()是函数对象的一个方法,它的作用是改变函数的调用对象,它的第一个参数就表示改变后的调用这个函数的对象,因此,this指的就是这第一个参数。call也是一样;apply与call的区别在于第二个参数,apply可以传递数组,而call只能是一个个数。
1234567891011var x = 0;function test() {console.log(this.x);}var o = {x: 1,m: function() {console.log(this.x);}};o.m.apply();
参考阮一峰dalao的博客Javascript的this用法
还有《你不知道的JavaScript 上卷》