首先给大家看一个代码
const jonas = {
year: 1995,
calcAge: function () {
console.log(this);
console.log(2038 - this.year);
},
greet: () => console.log(`Hey ${this.firstName}`),
};
jonas.greet();
这个会输出什么?
这个我们上篇文章中讲过,箭头函数本身不具备this关键字,箭头函数里面的this关键字会继承父元素,而这里的父元素就是全局函数,全局函数中没有对firstName进行定义,所以会打印上图所示的;
如果我们使用var声明函数,那么就会特别危险,会被箭头函数访问到
var firstName = 'IT知识一享';
const jonas = {
year: 1995,
calcAge: function () {
console.log(this);
console.log(2038 - this.year);
},
greet: () => console.log(`Hey ${this.firstName}`),
};
jonas.greet();
为什么是这样,我们在上个文章中也说明了,全局函数是什么函数?就是window函数,使用var声明的函数,会存入window函数中,所有上述代码是可以被访问到的;所以这是非常危险的;
所以在实际开发中,尽量不要使用var关键字去声明函数,也尽量不要使用箭头函数去作为对象的方法!
现在再看下普通函数的一个陷阱,看下面的代码
var firstName = 'IT知识一享';
const jonas = {
year: 1995,
calcAge: function () {
console.log(this);
console.log(2038 - this.year);
const isMillenial = function () {
console.log(this.year >= 1981 && this.year <= 1996);
};
isMillenial();
},
greet: () => console.log(`Hey ${this.firstName}`),
};
jonas.greet();
jonas.calcAge();
为什么函数中读取不到对象中的year呢?
在 calcAge 方法中,当调用 isMillenial() 时,它被视为直接的函数调用,而不是作为对象的方法调用。因此,this 的值将绑定到全局对象或 undefined,而不是 jonas 对象。
那么有什么解决方法呢?
第一种:ES6之前的解决方案
var firstName = 'IT知识一享';
const jonas = {
year: 1995,
calcAge: function () {
console.log(this);
console.log(2038 - this.year);
const self = this;
const isMillenial = function () {
console.log(self.year >= 1981 && self.year <= 1996);
};
isMillenial();
},
greet: () => console.log(`Hey ${this.firstName}`),
};
jonas.greet();
jonas.calcAge();
第二种:使用箭头函数
var firstName = 'IT知识一享';
const jonas = {
year: 1995,
calcAge: function () {
console.log(this);
console.log(2038 - this.year);
const isMillenial = () => {
console.log(self.year >= 1981 && self.year <= 1996);
};
isMillenial();
},
greet: () => console.log(`Hey ${this.firstName}`),
};
jonas.greet();
jonas.calcAge();
arguments关键字
const addExpr = function (a, b) {
console.log(arguments);
return a + b;
};
addExpr(2, 5);
addExpr(2, 5, 7, 5);
var addArrow = (a, b) => a + b;
arguments 是一个特殊的关键字,在 JavaScript 的函数中使用。它是一个类数组对象,包含了函数调用时传递的实际参数列表。
通过 arguments,我们可以在函数内部访问和操作函数调用时传递的参数,而无需提前定义形式参数。这对于那些参数个数不确定或者想要接收任意数量的参数的函数来说非常有用。
以下是一些常见的用途和功能:
- 访问参数:使用 arguments 可以按索引访问传递给函数的每个参数的值。例如,arguments[0] 表示第一个参数,arguments[1] 表示第二个参数,依此类推。
- 参数长度:通过 arguments.length 可以获取传递给函数的参数个数。
- 迭代参数:由于 arguments 是类数组对象,可以像迭代数组一样使用循环遍历参数。
- 传递参数:可以将 arguments 对象作为参数传递给其他函数。这对于需要将接收到的参数传递给其他函数进行处理或转发的情况非常有用。
需要注意的是,虽然 arguments 是一个类数组对象,但它并不是一个真正的数组,因此不能直接使用数组的方法。如果需要在 arguments 上使用数组方法,可以将其转换为真正的数组,例如通过 Array.from(arguments) 或者 Array.prototype.slice.call(arguments) 来实现。
然而,自ES6起,推荐使用剩余参数(rest parameters)语法来代替 arguments 的使用,因为剩余参数更易读、更灵活,并且能够直接返回一个真正的数组。