首頁  >  問答  >  主體

javascript - 函數嵌套中,this指向物件會發生怎麼樣的變化?

我寫了一個demo,其功能是滑鼠移入時長方形塊長度變長,然後高度變高,遇到如下問題:

在執行下面這段函數嵌套時

    op[0].onmouseover = function(){
        that = this;
        changeStyle(that,'width',400,function(){
            changeStyle(that,'height',300);
        });
    }

必須使用that=this傳參,否則瀏覽器會報如下錯誤

Uncaught TypeError: Failed to execute 'getComputedStyle' on 'Window': parameter 1 is not of type 'Element'.

我在最後貼出了整套程式碼,我想知道為什麼用that=this傳參能解決問題?不傳參的話this兩次分別指向了誰? chrome和firefox有沒有什麼好的調試方法能監視每一次this值的變化並顯示出來?

html程式碼:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>animation</title>
    <link rel="stylesheet" href="animation.css" />
</head>
<body>
    <p class="wrap"></p>
    <script src="animation.js"></script>
</body>
</html>

css程式碼:

.wrap{
    width: 200px;
    height: 100px;
    margin: 10px;
    background-color: #f00;
    border: 4px solid black;
}

js程式碼:

window.onload = function(){
    var op = document.getElementsByTagName('p');
    op[0].timer = null;
    op[0].onmouseover = function(){
        that = this;
        changeStyle(that,'width',400,function(){
            changeStyle(that,'height',300);
        });
    }
}
function changeStyle(obj,attr,iTarget,fn){
    clearInterval(obj.timer);
    var curValue = 0;
    obj.timer = setInterval(function(){
        curValue = parseInt(getStyle(obj,attr));
        var speed = (iTarget - curValue) / 20;
        speed = (speed > 0) ? Math.ceil(speed) : Math.floor(speed);
        if (curValue == iTarget) {
            clearInterval(obj.timer);
            if (fn) {
                fn();
            }
        }
        else{
            obj.style[attr] = curValue + speed + 'px';    
        }
    },30);
}
function getStyle(obj,attr){
    if (obj.currentStyle) {
        return obj.currentStyle[attr];
    }
    else{
        return getComputedStyle(obj,null)[attr];
    }
}
習慣沉默習慣沉默2711 天前636

全部回覆(5)我來回復

  • 黄舟

    黄舟2017-05-19 10:12:31

    透過事件呼叫的函數的this指向觸發該事件的元素,所以op[0].onmouseover事件呼叫函數的this指向的是op[0];

    changeStyle函數傳入的回呼函數的this指向的是window,因為 if (fn) { fn();}相當於window呼叫了該函數

    如果想追蹤程式碼的執行情況可以採用斷點調試,能看到各個變數在運行中的賦值情況

    回覆
    0
  • 我想大声告诉你

    我想大声告诉你2017-05-19 10:12:31

    this代表函數運行時,自動產生的一個內部對象,只能在函數內部使用。
    隨著函數使用場合的不同,this的值會改變。但是有一個總的原則,那就是this指的是,呼叫函數的那個物件

    我想你可以看看阮一峰的這篇:http://www.ruanyifeng.com/blo...

    回覆
    0
  • 曾经蜡笔没有小新

    曾经蜡笔没有小新2017-05-19 10:12:31

    忘掉this指向的煩惱吧,(es6)請使用箭頭函數

    回覆
    0
  • PHP中文网

    PHP中文网2017-05-19 10:12:31

    如果不傳that,你的change函數,改變的是誰的樣式,你知道嗎?如果直接用this,this是指向window的,如一樓所說,斷點,一斷就知道

    回覆
    0
  • 给我你的怀抱

    给我你的怀抱2017-05-19 10:12:31

    若不用that=this將this綁定到目前詞法作用域,那麼this指向的就是全域物件window,這就屬於this的預設綁定。

    回覆
    0
  • 取消回覆