箭头函数与普通函数有什么区别?
1.箭头函数与function定义函数的写法:
普通函数:function fn(a,b){};
箭头函数:var fn = (a,b)=>{};
2.this指向:
使用function定义的函数,this的指向是随着调用环境的变化而变化的,而箭头函数中的this指向是固定不变的,一直指向的是定义函数的环境
普通函数:
function fn(){ console.log(this) }
var obj = {aa: fn};
fn(); // window
obj.aa(); // obj
箭头函数:
var fn = ()=>{ console.log(this) };
var obj = {aa: fn};
fn(); // window
obj.aa(); // window
3.构造函数
普通函数:
每个新定义(function)的函数都有它自己的 this值(在构造函数的情况下是一个新对象,在严格模式的函数调用中为 undefined,如果该函数被称为“对象方法”则为基础对象等)
function Fn(){ this.a = 1; }
var obj = new Fn();
obj.a = 1;
箭头函数:(箭头函数表达式的语法比函数表达式更短,并且不绑定自己的this,arguments,super或 new.target。这些函数表达式最适合用于非方法函数,并且它们不能用作构造函数。)
// 注:严格模式下,箭头函数中的this指向window
// 箭头函数不会创建自己的this;它使用封闭执行环境上下文的this值。
// 箭头函数中的this是无法被修改的(call,apply,bind)
// 箭头函数中也没有arguments.
// 箭头函数没有prototype属性。
var Fn = ()=> { this.a = 1; }
var obj = new Fn(); // Fn is not a constructor
4.变量提升
由于js的内存机制,function的级别最高,而用箭头函数定义函数的时候,需要var(let const定义的时候更不必说)关键词,而var所定义的变量不能得到变量提升,故箭头函数一定要定义于调用之前!
普通函数:
fn();
function fn(){}
箭头函数:
Fn(); // Fn is not a function
var Fn =()=>{};
面试题一道
var x = 2;
var y = {
x: 3,
z:(function(x){
this.x *= x;
x+=2;
return function(n){
this.x *= n;
x += 3;
console.log(x);
}
})(x)
// 自执行函数先执行,所以自执行函数的this执行window
// 自执行函数执行完成后,把执行的结果赋值给对象的属性
}
var m = y.z;
m(4);
y.z(5);
console.log(x,y.x)
解析
/* *
程序从上到下执行 遇到var m = y.z; 执行立执行函数,这个函数的this指向window,遇到return,把return返回的地址值赋值给y.z为AAA
所以
this.x *= x
传入的x为全局的x=2;
window.x = window.x * x = 2 * 2 = 4 此时全局的x = 4
x += 2;
x = x + 2; 传入的是2; 2 + 2 = 4;此时作用域中的x为4(重点)
执行m(4)
相当于执行
return function(n){
this.x *= n;
x += 3;
console.log(x);
}
谁调用this指向谁,此时是window调用
window.x = window.x * n = 4 * 4 = 16
x+=3; x此函数中没有,向上级作用欲中查找为4 ; x+3 = 7
遇到y.z(5)执行,相当于执行之前的AAA(堆内存地址)
return function(n){
this.x *= n;
x += 3;
console.log(x);
}
谁调用this指向谁,此时是y调用,this执行y
y.x = y.x * n = 3 * 5 = 15;
x += 3; x在当前函数中没有,向上级作用域查找,上级作用域的x值为7
所以x+=3 = 7+3 = 10
cosnole.log(x,y.x);
x = 16
y.x = 15
*/