this指向问题

以下函数利用classaname遍历标签属性的时候,企图触发事件,将本函数的调用者以this的状态传递给下一个函数,但是在调用的时候,this更改了指向,最后打印出来的结果是,this指向window;最后不得已,将move(this),改为move(x[i])才打印正常;

window.οnlοad=function(){
var x=document.getElementsByClassName("div");

for(var i=0;i<x.length;i++){

x[i].οnclick=move(this);

}}

function move(member){
console.log(member);

}  ;  //  window

于是就this进行探索,以下是对this指向的总结,希望有所收获:

1,this 的指向在函数定义的时候不能够确定,它指向的永远是最后调用它的那位;

function a(){
var  name="bob";

console.log(this.name);

}

a(); // undefined; 最后是在window执行环境中调用,在window中并没有找到name;

2,如果一个函数中有this,这个函数中有多个对象包裹着this,尽管this是被最外层对象调用的,this仍然指向离自己最近的那个对象。

var o={
a:{

b:{

m:10,

fn:function(){
console.log(this);

};  }  }  }

window.o.a.b.fn();    // m:10,fn:f   

打印结果也就是对象b,this并没有指向window,而是指向b.

3,当this遇到return时:
 如果return的值是一个对象,那么this就指向那个return过来的对象,

function a(){

this.age=10;

return  {} 或者 return  function(){}  

}  

var  m=new a();

m.age; //undefined;

反之,如果return的不是对象,那么this还是指向函数实例,其中null虽然是对象,但是this还是指向函数实例;

function a(){

this.age=10;

return  1  或者  return  undefined;

}   

var  m=new a();

m.age;  //  10;

4,每个函数在创建的时候都会产生一个this和一个arguments;而且这个函数的内部函数还不能够直接访问到这个函数的this,但是如果把外部函数中的this用一个变量保存起来,内部的函数(比如闭包)虽然不能直接访问this,但是却可以访问外部函数的变量;

var name = "The Window"; 
 
var object = {    

name : "My Object", 
 
getNameFunc : function(){ 

 var that = this;      

 return function(){      

  return that.name;  

      };     } }; 

 alert(object.getNameFunc()());  //"My Object" 

5,全局作用域或者普通函数中this指向全局对象window

//直接打印
console.log(this) //window

//function声明函数
function bar () {console.log(this)}
bar() //window

//function声明函数赋给变量
var bar = function () {console.log(this)}
bar() //window

//自执行函数
(function () {console.log(this)})(); //window

6,方法调用中谁调用this指向谁

//对象方法调用
var person = {
    run: function () {console.log(this)}
}
person.run() // person

//事件绑定
var btn = document.querySelector("button")
btn.onclick = function () {
    console.log(this) // btn
}
//事件监听
var btn = document.querySelector("button")
btn.addEventListener('click', function () {
   console.log(this) //btn
})

//jquery的ajax
 $.ajax({
    self: this,
    type:"get",
    url: url,
    async:true,
    success: function (res) {
        console.log(this) // this指向传入$.ajxa()中的对象
        console.log(self) // window
    }
   });
 //这里说明以下,将代码简写为$.ajax(obj) ,this指向obj,在obj中this指向window,因为在在success方法中,独享obj调用自己,所以this指向obj

7,在构造函数或者构造函数原型对象中this指向构造函数的实例 

//不使用new指向window
function Person (name) {
    console.log(this) // window
    this.name = name;
}
Person('inwe')
//使用new
function Person (name) {
      this.name = name
      console.log(this) //people
      self = this
  }
  var people = new Person('iwen')
  console.log(self === people) //true
//这里new改变了this指向,将this由window指向Person的实例对象people

 8,this的指向可以强制改变:

利用 bind(),apply(),call();

callback(); ----->callback.bind(  object1  );

可以使得callback()函数中的this强制指向对象object1;

9,对于函数内部的this,谁调用它,它就指向谁;若没有明确的调用对象,即使一个函数定义在另一个函数内部,this仍然指向window;

function fire(){
function wall(){
console.log(this);}

wall();

}

fire();   // window;

第二个例子:

var  obj={

name:"bob",

fire:function(){
function wall(){
console.log(this);

}

wall();  //没有明确的对象调用它,仅仅是独立的函数在执行;

}  }

obj.fire();  //window;

凡是作为独立函数调用,无论它的位置在哪里,它的行为表现,都和直接在全局环境中调用无异{

10,一个函数被一个对象包含的时候,它的this隐式绑定到这个对象上:

var  obj={

a:  1,

fire:function(){
console.log(this.a);

}
obj.fire(); //1 

和这个函数效果相同:

function fire(){
console.log(this.a);

}

var obj={

a:  1,

fire:fire

}
obj.fire(); // 1

fire函数并不会因为它被定义在obj对象的内部和外部而有任何区别,也就是说在上述隐式绑定的两种形式下,fire通过this还是可以访问到obj内的a属性,这告诉我们: 

1.  this是动态绑定的,或者说是在代码运行期绑定而不是在书写期

2.  函数于对象的独立性, this的传递丢失问题 

11,this隐式绑定丢失与寻回:

var a=2;

var o={

a: 1,

fire:function(){
console.log(this.a);

}

}

function  ani(fn){
fn();}

ani(obj.fire);   // 2

本来隐式绑定this应该指向obj,但是由于隐式绑定丢失,所以this指向的是window;

那么什么情况下this会丢失隐式绑定呢?只有一种情况:当包含this的函数没有执行,而是被当作值传递,或者被当作回调函数的参数的情况下,会丢失。利用call()函数将丢失的this找回来:

var a=1;

var obj={

a: 2,

fire: function(){
console.log(this.a);

}}

var  wall=obj.fire;  //此处函数被当作值传递,丢失this

wall.call(obj);  //  2                    call()函数使wall的this指向obj

另外,在《javascript高级程序设计》中,提到一段程序,就是因为函数未直接执行,而是被当作参数传递而丢失this:

var handler = {    

 message: "Event handled", 
 
handleClick: function(event){

alert(this.message);     } };

var btn = document.getElementById("my-btn");

EventUtil.addHandler(btn, "click", handler.handleClick);   //警告框弹出:undefined

因为handler.handleClick未执行函数,仅仅当作参数被调用,那么我们执行它就可以避免this丢失:

EventUtil.addHandler(btn, "click", function(event){

handler.handleClick(event) }   );     // 打印结果是Event handled;  

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值