一、this
JavaScrip的this总是指向一个对象,而具体指向哪个对象是在运行时基于函数的执行环境动态绑定的,而非函数被声明时的环境。
二、this的指向
根据运用情景可分为四类:
1.作为对象的方法调用;
2.作为普通函数调用;
3.构造器调用;
4.Function.prototype.call或Function.prototype.apply调用。
1.作为对象的方法调用:
当函数作为对象的方法被调用时,this指向该对象:
var obj = { a :1, getA:function () { alert(this === obj);//true alert(this.a) //1 } };
obj.getA();
2.作为普通函数调用;
当函数不作为对象的属性被调用时,即该函数为普通函数时,此时this的指向时全局对象,在浏览器的js中,这个全局对象也就是window。
window.name = 'hello world'; var getName = function () { return this.name; } console.log(getName());//hello world
或
window.name = 'hello world'; var obj = { name : 'ling', getName : function () { return this.name; } }; var getName = obj.getName; console.log(getName()); //hello world console.log('obj----'+obj.getName());//obj----ling
那么怎么解决这个问题呢。。。。。在书上居然也讲了我之前写前端时公司老同志教我的方法,哈哈哈~~~那就是“that”大法!
//假设节点id为abc window.id = 'ling'; document.getElementById('ling').onclick = function () { alert(this.id); //abc var callback = function () { alert(this.id);//ling } callback(); };
方法如下~~
//假设节点id为abc window.id = 'ling'; document.getElementById('ling').onclick = function () { var that = this; var callback = function () { alert(that.id);//abc } callback(); };
3.构造器调用;
js中没有类,但是我们可以从构造器中创建对象,同时也提供了new运算符使得构造器看起来更像一个类。
当使用new运算符调用函数时,该函数总会返回一个对象,通常情况下。构造器里的this就指向这个返回的对象。
var MyClass = function () { this.name = 'ling'; } var obj = new MyClass(); console.log(obj.name);//ling
但是要特别注意如果函数显示地返回一个对象,那么this指的便是这个显示对象。若显示返回的是非对象类型(string等),则不会出现下面的问题。
var MyClass = function () { this.name = 'ling'; return { a : 'abc' }; } var obj = new MyClass(); console.log(obj.name);//undefined console.log(obj.a);//abc
4.Function.prototype.call或Function.prototype.apply调用。
与普通函数相比,用call()和apply()可以动态改变传入函数的this指向。
var obj1 = { name: 'ling', getName : function () { return this.name } } var obj2 = { name : 'abc' } console.log(obj1.getName());//ling console.log(obj1.getName.call(obj2));//abc