面试题201412——core this作用域


二、setTimeout与while的执行顺序

var t=true;
setTimeout(function(){
    console.log(123);
    t=false;
},1000);

while(t){ }
console.log('end');

令我吃惊的是,在chrome中,竟然崩溃了。

解答:

是不会输出END的,因为,执行这条语句的时候是先执行 while语句,再执行setTimeout里面的语句。因为T=TURN ,所以while会一直循环,造成浏览器假死。

因为javascript引擎是单线程执行的,while循环那里执行的时候,settimeout里面的函数根本没有执行的机会,这样while那里永远为真,造成死循环。

一、在对象中this,及setTimeout的this

var Obj = function(msg){
    console.log(this);//new Obj时打印: Obj {}
    this.msg=msg;
    console.log(this);//new Obj时打印: Obj {msg: "abc"}
    this.shout=function(){
        console.log(this);//2秒后,Window {top: Window, window: Window, location: Location, external: Object, chrome: Object…}
        alert(this.msg);// alert [ undefined ]
    }
    this.waitAndShout=function(){
        console.log(this);//调用aa.waitAndShout()时打印: Obj {msg: "abc", shout: function, waitAndShout: function}
        setTimeout(this.shout, 2000);
    }
}

var aa=new Obj("abc");//可见构造函数的this和方法中的this都指向该对象
aa.waitAndShout();

既然是new了一个对象,那么this作用域就指向该对象,里面包含属性和方法

补充一下,如果是如下调用

Obj(“abc”);//什么也不输出

Obj.waitAndShout();//报错 Uncaught TypeError: undefined is not a function

进入正题:

2秒后,结果alert的是undefined

原因是什么呢?

首先尝试:

var _this = this;
this.waitAndShout=function(){
    console.log(this);//调用aa.waitAndShout()时打印: Obj {msg: "abc", shout: function, waitAndShout: function}
    setTimeout(_this.shout, 2000);
}

但是,这种方法也不行,alert的依然是undefined,即shout方法的作用域依然是window。

换个写法再试试

var Obj = function(msg){
    this.msg=msg;
    this.shout=function(){
        console.log(this);//2秒后,Obj {msg: "abc", shout: function, waitAndShout: function}
        alert(this.msg);// alert [ undefined ]
    }
    var _this = this;
    this.waitAndShout=function(){
        setTimeout(function(){
            _this.shout();
            //this.shout();//Uncaught TypeError: undefined is not a function
            console.log(this);//Window {top: Window, window: Window, location: Location, external: Object, chrome: Object…}
        }, 2000);
    }
}

真相大白,setTimeout的this始终指向window,最开始的调用方式this.shout找到了正确的方法,但方法的this不是指向当前对象,而是window。

结论:setTimeout改变了this的执行,变为指向window。


发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>