当前位置:编程学习 > JAVA >>

javascript中的this

javascript里避免不了用到this,不过this的作用域scope问题常常会不经意间发送变化,导致程序出现错误或异常。
这里只对this做一些简单的总结,更详细的行为还需要大家去琢磨。
this都是用在函数function里的(废话...)。这里要说明一点,js里的函数就是一个普通函数(没有成员函数这一说法,准确的说),无论它定义在哪里。
所以一个函数可以绑定到任何对象上去用,这时成这个被绑定的对象为该函数的owner。ok,函数里的this就是指向他的owner的。
this的多变就是由于他的owner常常发生变化。举个例子:
< script type = "text/javascript" >
    var o = {
        _name : 'o' , // used for debug
        foo : function (){
            console . log ( this . _name );
        }
    }
   
    o . foo ();
</ script >


这里o.foo就是一个函数(应该叫函数指针,指向一个函数function(){console.log(this._name);})。那么执行 o.foo()的时候,foo(确切说是foo指向的函数)的owner就是o,里面的this也是o,运行结果会打印'o';
为什么说是函数指针?再继续这个例子:
< script type = "text/javascript" >
    var fn = o . foo ;
    fn ();
</ script >
      这里fn = o.foo并不是系统把o.foo这个函数copy给了fn,而是copy了o.foo的指针值,让fn也指向函数funtion(){console.log(this._name);}。
这时候执行fn什么效果呢?fn(again,确切说是fn指向的函数)“没了”owner,这时系统就会把window这个全局对象传给this,也就是说fn(不again了)的owner是window。
因为window里并没定义_name属性,这时会输出undefined。再测试一下,给window添加个熟悉_name;
        < script type = "text/javascript" >
            window . _name = 'window' ;
            fn ();
        </ script >
        OK,上面说了函数里的this到底指向的那个对象:执行时的owner。下面看看this为何会在实际应用中变化莫测。
根本原因很简单,他的owner变了,像上面的o.foo和fn两个例子就可以说明。以下举几个例子来说它经常的变化方式:
1. 对象里的函数(你知道这么说是不对的)调用了其他对象的函数,这时this就会变化
        < script type = "text/javascript" >
            // 例如常用的ajax
            var o2 = {
                xhr : null ,
                execute : function (){
                    xhr . onreadystatuschange = function (){
                        this . _traceXhr ( xhr ); // error here! 'this' is xhr now
                    }
                },
                _traceXhr : function ( _xhr ){
                    console . log ( _xhr );
                }
            }
        </ script >
        这里的错误比较明显了吧,function() {this._traceXhr(xhr);}是个函数,这时候是绑定到xhr上运行的,那里面的this自然就指向xhr而不再是o2。
正确的写法是o2._traceXhr(this);    (ps,实际的应用中可能是这样的,一般会定义一个“类”,噢o2只是这个类的实例,那么定义类的时候需要这样写:
        < script type = "text/javascript" >
function ClazzO (){
}

ClazzO . prototype . xhr = null ;
ClazzO . prototype . execute = function (){
var _self = this ;
xhr . onreadystatuschange = function (){
_self . _traceXhr ( this );
}
}
ClazzO . prototype . _traceXhr = function ( _xhr ){
console . log ( _xhr );
}
</ script >
        execute里用一个临时变量保存一下善变的this,防止到了onxxxchange里面的时候找不到他了。
主要是这一类问题导致this的变化,另外还有一些是和dom对象联系在一起的

2. dom对象event里的this
a: <input type = "button" id = "a" onclick = " javascript : console . log ( this . value ) " value = "click me a" />
这种写法输出结果和我们想的一样:click this。但有些同学就提意见了,在html里面夹杂太多的js代码不好,而且有时由于函数太复杂含有' or "导致根本不能写在这里面,最好抽出来放到一个函数里:
b: <input type = "button" id = "b" onclick = " javascript : clicked () " value = "click me b" />
<script type = "text/javascript" >
function clicked () {
console . log ( this . value );
}
</script>
来看浏览器帮我们做了什么: onclick="[js code]"
浏览器会帮我们生成(这点我不确定,但按这种方式理解可以行得通)
[dom].onclick = function() {[js code]}
好,看看上面两个都发生了什么:
        <script type = "text/javascript" >
// a
document . getElementById ( "a" ). onclick = function () {
console . log ( this . value );
}
// b
document . getElementById ( "b" ). onclick = function () {
clicked ();
}
</script>
        解释清楚了吧。还是owner变 了

3. 浏览器行为
这一点我只是顺便看到说ie和ff在绑定事件上的区别(attachEvent、addEventListener)继续看例子:
        c: <input type = "button" id = "c" value = "click me c" />
<script type = "text/javascript" >
var c = document . getElementById ( "c" );
if ( document . attachEvent ) {     // for ie
c . attachEvent ( 'onclick' , clicked );
} else {
c . addEventListener ( 'click' , clicked , false );
}
</script>
       ie下输出undefined, ff下输出click me c, why? 加点debug信息再看看
        d: <input type = "button" id = "d" value = "click me d" />
<script type = "text/javascript" >
function clicked2 () {
console . log ( this , arguments );
for ( var i = 0 ; i != arguments . length ; ++ i ) {
console . log ( 'arg' , i , ':' , arguments [ i ]);
}
}
var d = document . getElementById ( "d" );
if ( document . attachEvent ) {     // for ie
d . attachEvent ( 'onclick' , clicked2 );
} else {
d . addEventListener ( 'click' , clicked2 , false );
}
<

补充:web前端 , JavaScript ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,