院校门户网站建设方案,php网站开发linux,html零基础教程,盛大印刷公司网页设计前言 #x1f4eb; 大家好#xff0c;我是南木元元#xff0c;热衷分享有趣实用的文章#xff0c;希望大家多多支持#xff0c;一起进步#xff01; #x1f345; 个人主页#xff1a;南木元元 目录
什么是箭头函数
箭头函数和普通函数的区别
更简洁的语法
箭头函数…前言 大家好我是南木元元热衷分享有趣实用的文章希望大家多多支持一起进步 个人主页南木元元 目录
什么是箭头函数
箭头函数和普通函数的区别
更简洁的语法
箭头函数没有自己的this
箭头函数的this不会改变
箭头函数没有prototype属性
箭头函数不能作为构造函数
箭头函数不能使用arguments对象
箭头函数不能用作Generator函数
箭头函数不适用的场景
结语 什么是箭头函数
箭头函数是ES6ECMAScript 6新增的使用箭头语法定义函数表达式的能力。任何可以使用函数表达式的地方都可以使用箭头函数并且它的语法比传统的函数表达式更加简洁。
// 函数表达式
let functionExpressionSum function(a, b) {return a b;
}// 箭头函数
let arrowSum (a, b) {return a b;
}
下面就来详细讲解一下箭头函数和普通函数的区别。
箭头函数和普通函数的区别
更简洁的语法
如果只有一个参数可以不用括号。只有没有参数或多个参数的情况下才需要使用括号。
// 只有一个参数可以不用括号以下两种写法都有效
let double (x) { return 2 * x; };
let triple x { return 3 * x; };// 没有参数需要括号
let getRandom () { return Math.random(); };// 多个参数需要括号
let sum (a, b) { return a b; };// 无效的写法
let multiply a, b { return a * b; };
如果函数体的返回值只有一句可以省略大括号省略大括号会隐式返回这行代码的值。
// 以下两种写法都有效而且返回相应的值
let double (x) { return 2 * x; };
let triple (x) 3 * x;// 无效的写法
let multiply (a, b) return a * b;
如果函数体不需要返回值且只有一句话可以给这个语句前面加一个void关键字。
// 最常见的就是调用一个函数
let fn () void doesNotReturn();
由于其更简洁的语法箭头函数的一个用处就是简化回调函数。
// 普通函数写法
var result arr.sort(function (a, b) {return a - b;
});// 箭头函数写法
var result arr.sort((a, b) a - b);
箭头函数没有自己的this
所有函数在执行时会创建一个函数执行上下文普通函数的执行上下文中会有一个变量this而箭头函数没有箭头函数不会创建自己的this对象只会继承在自己作用域的上一层this。
var id Global// 箭头函数定义在全局作用域
let fun1 () {console.log(this.id)
}fun1() // Global
输出 可以⽤Babel理解⼀下箭头函数
// ES6
const obj { getArrow() { return () { console.log(this obj); }; }
}// 转化后的ES5
var obj { getArrow: function getArrow() { var _this this; return function () { console.log(_this obj); }; }
};上面代码中转换后的ES5版本清楚地说明了箭头函数里没有自己的this而是引用外层的this。
箭头函数的this不会改变
箭头函数没有自己的this所以箭头函数中this的指向在它定义时就已经确定了之后不会改变。
var name GLOBAL;
var obj {name: 南木元元,getName1: function(){console.log(this.name);},getName2: () {console.log(this.name);}
};
obj.getName1(); // 南木元元
obj.getName2(); // GLOBAL
输出结果 对象obj的方法b是使用箭头函数定义的这个函数中的this就永远指向它定义时所处的全局执行环境中的this即便这个函数是作为对象obj的方法调用this依旧指向Window对象。所以其实定义对象的方法是不适合使用箭头函数的。
此外call()、apply()、bind()等方法也不能改变箭头函数中this的指向。
var id Global;
let fun1 () {console.log(this.id)
};
fun1(); // Global
// this的指向不会改变
fun1.call({id: Obj}); // Global
fun1.apply({id: Obj}); // Global
fun1.bind({id: Obj})(); // Global
输出结果 箭头函数没有prototype属性
来看下面代码。
let fn function(name) {console.log(name);
}
let fn2 name console.log(name);
console.log(fn.prototype);
console.dir(fn2.prototype);
输出结果 箭头函数不能作为构造函数
上面说了箭头函数没有自己的this没有prototype属性所以也就不能用作构造函数即不可以对箭头函数使用new命令否则会抛出错误。
let fn (name, age) {this.name name;this.age age;
}// 报错
let p new fn(南木元元, 18);
输出结果 为什么会这样呢这其实跟new内部实现有关new的实现步骤如下
创建一个新的空对象设置原型将对象的原型设置为函数的prototype对象让函数的this指向这个对象执行构造函数的代码返回新的对象
function myNew(constructor, ...args) {// 基于原型链 创建一个新对象并且继承构造函数constructor的原型对象prototype上的属性let newObj Object.create(constructor.prototype);// 执行构造函数并让this指向这个新对象let res constructor.apply(newObj, args); // 如果函数的执行结果有返回值并且是一个对象, 返回执行的结果, 否则, 返回新创建的对象return typeof res object ? res: newObj;
}
上面的第二、三步箭头函数都是没有办法执行的。
箭头函数不能使用arguments对象 arguments是一个对应于传递给函数的参数的类数组对象。 arguments是在所有普通函数中都可用的一个类数组对象类数组不是数组而是类似数组的对象它除了length属性和索引之外不能调用数组的方法。
所以通常会使用Array.prototype.slice.call(arguments)/Array.from(arguments)/[...arguments]的方式将它转换成一个数组。
let fn function () {console.log(arguments);console.log(Array.prototype.slice.call(arguments));
}
fn(param1, param2);
输出结果 箭头函数不可以使用arguments对象该对象在函数体内不存在。
let fn (name, age) console.log(arguments);
// 报错
fn(南木元元, 18);
输出结果 在箭头函数中访问arguments实际上获得的是它外层函数的arguments值。
let fn function(name, age) {let fn2 name {console.log(arguments);}fn2();
}
fn(南木元元, 18); 输出结果 那么如果一定要用呢可以用ES6中的rest参数代替。
let fn (...args) console.log(args);
fn(南木元元, 18);
输出结果 上述代码使用了rest参数形式为...变量名获取函数的多余参数这样就不需要使用arguments对象了。
箭头函数不能用作Generator函数
箭头函数内部不可以使用yield命令因此箭头函数不能用作Generator函数。
let fn function *() {yield 南木元元;
}
let p fn();
console.log(p.next()); 输出 let fn *() {yield 南木元元;
}
let p fn();
console.log(p.next()); 输出 箭头函数不适用的场景
对象方法且方法内部使用this
第一个场景上面提到过定义对象的方法并且方法内部使用this时不适合用箭头函数。
var name GLOBAL;
var obj {name: 南木元元,getName: () {console.log(this.name);}
};
obj.getName(); // GLOBAL
上述代码中调用obj.getName()方法时如果是普通函数该方法内部的this指向调用它的那个对象如果写成上面那样的箭头函数使得this指向了全局对象因此不会得到预期结果。这是因为对象不构成单独的作用域导致getName箭头函数定义时的作用域就是全局作用域。
需要动态this
第二个场合是需要动态this的时候也不应使用箭头函数。
var button document.getElementById(btn);
button.addEventListener(click, () {console.log(this); //由于使用了箭头函数this会指向全局对象Window
});
上面代码运行时点击按钮会报错因为button的监听函数是一个箭头函数导致里面的this就是全局对象。如果改成普通函数this就会动态指向被点击的按钮对象。
结语
本文主要总结了箭头函数和普通函数的几大区别箭头函数虽然语法简洁但也有一些场合不适用需要根据不同的场景选择使用合适的函数。
如果此文对你有帮助的话欢迎关注、点赞、⭐收藏、✍️评论支持一下博主~