js程序题

200 阅读2分钟

1、var和函数的提前声明

function fn(a){
    console.log(a);
    var a = 2;
    function a(){
    }
    console.log(a);
}
fn(1);

输出:

原因:var和function是会提前声明的,而且function是优先于var声明的(如果同时存在),所以提前声明后输出的a是一个函数,然后又对a进行了重新赋值,所以第二次输出的是2。

2、字符串方法

var foo = 'string';
foo.substring(2,1);
console.log(foo);

输出:string

note:sclice,substr,substring都不改变原字符串。

3、this指向

var name = 'zhangsan';
var a = {
    name:'lisi',
    fn:function(){
        console.log(this.name);
    }
};
var f = a.fn;
f();         //zhangsan   在浏览器中this指向window,输出zhangsan,node环境下this指向global,输出undefined
a.fn();      //lisi        this指向a对象
a.fn.call({name:'wangwu'});   //wangwu     修改了this指向

考点:

1、

var f = a.fn;

f();

this永远指向的是最后调用它的对象,虽然函数fn是被对象a所引用,但是在将fn赋值给变量f的时候,并没有执行。最后调用f()的对象是window,所以this指向window。

2、附加考点

网页上最终指向了window对象。

node上最终指向了global对象。

4、this指向

var length = 0;
function fn(){
    console.log(this.length);
}
var obj = {
    length:5,
    method:function(fn){
        fn();
        arguments[0]();
    }
};
obj.method(fn,1);

输出:

0

2

在执行obj.method()时,如果函数内部有this,即(fn.call(this)),则this确实指向obj。如果fn(),fn()函数绑定的对象是window(fn中this的指向跟fn的运行环境有关,跟执行环境obj无关),所以输出0。

全局函数fn同时也属于arguments数组中的一员,即当作为arguments成员之一调用的时候,其作用域就绑定到了arguments上,this也就是指向了arguments对象,所以arguments[0]()这段代码调用了身为成员的fn()函数,this.length就等于是arguments.length,又因为method传入的参数为2个,所以最后输出2。

5、变量提升和函数作用域

var a = 1;
function test(){
    console.log(a);//undefined
    var a = 2;
    console.log(a);//2
    a = 3;
}
test();

因为test里面的a进行了变量提升,所以第一次输出undefined。

a赋值为2之后,输出2。

因为函数里面定义了局部变量a,所以是不会找全局的a变量的。

区别:

var a = 1;
function test(){
    console.log(a);//Uncaught ReferenceError: a is not defined
    console.log(this);  //window
    let a = 2;          //注意这里没有进行变量提升
    console.log(a);     //2(前提注释掉上一条console.log(a))
    a = 3;
}
test();
var a = 1;
function test(){
    console.log(this);    //window
    let a = 2;
    console.log(this.a);//注意这里有this   1
    a = 3;
}
test();