发布时间:2023-08-22 12:30
普通函数
function add(num) {
return num + 10
}
箭头函数
const add = num => num + 10;
这句话需要注意的是,箭头函数的外层如果有普通函数,那么箭头函数的this就是这个外层的普通函数的this,箭头函数的外层如果没有普通函数,那么箭头函数的this就是全局变量。
下面这个例子是箭头函数的外层有普通函数。
let obj = {
fn:function(){
console.log('我是普通函数',this === obj) // true
return ()=>{
console.log('我是箭头函数',this === obj) // true
}
}
}
console.log(obj.fn()())
下面这个例子是箭头函数的外层没有普通函数。
let obj = {
fn:()=>{
console.log(this === window);
}
}
console.log(obj.fn())
// true
箭头函数没有arguments、super、new.target的绑定,这些值由外围最近一层非箭头函数决定。
下面的这个函数会报错,在浏览器环境下。
let f = ()=>console.log(arguments);
//报错
f(); // arguments is not defined
下面的箭头函数不会报错,因为arguments是外围函数的。
function fn(){
let f = ()=> {
console.log(arguments)
}
f();
}
fn(1,2,3) // [1,2,3]
箭头函数可以通过拓展运算符获取传入的参数。
请看下面的代码
window.name = "window_name";
let f1 = function () {
return this.name;
};
let f2 = () => this.name;
let obj = { name: "obj_name" };
console.log(f1.call(obj)); //obj_name
console.log(f2.call(obj)); // window_name
console.log(f1.apply(obj)); // obj_name
console.log(f2.apply(obj)); // window_name
console.log(f1.bind(obj)()); // obj_name
console.log(f2.bind(obj)()); // window_name
由于不可以通过new关键字调用,所以没有构建原型的需求,所以箭头函数没有prototype这个属性。
let F = ()=>{};
console.log(F.prototype) // undefined
既然上文我们提到了arguments,那么下面我们就仔细讲讲这个arguments。
arguments对象是所有非箭头函数中都可用的局部变量,可以使用arguments对象在函数中引用函数的参数,此对象包含传递给函数的每一个参数,第一个参数在索引0的位置。
var args = Array.prototype.slice.call(arguments);
var args = [].slice.call(arguments);
const args = Array.from(arguments);
const args = [...arguments];
我们先看看下面这个函数,这个是可以正常运行的。
function factorial (n) {
return !(n > 1) ? 1 : factorial(n - 1) * n;
}
[1,2,3,4,5].map(factorial);
但是作为匿名函数则不行。
[1,2,3,4,5].map(function (n) {
return !(n > 1) ? 1 : /* what goes here? */ (n - 1) * n;
});
因此arguments.callee诞生了。
[1,2,3,4,5].map(function (n) {
return !(n > 1) ? 1 : arguments.callee(n - 1) * n;
});
所以arguments要想调用自身的匿名函数,可以通过arguments.callee来调用。