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();