js函数知识必记点

174 阅读4分钟

1:每个函数都是Function类型的实例,函数也是对象,函数名是指向函数对象的指针。
2:定义函数的方式包括函数声明,函数表达式,箭头函数,Function构造函数(不推荐,很少使用)。
3:箭头函数如果只有一个参数,可以不用写括号,如果有多个或者没有则需要写括号。
4:箭头函数中也可以不用写大括号,省略大括号的话函数体只能有一行代码,比如一个赋值操作或者一个表达式,而且会隐式的返回这行代码的值。
5:箭头函数不能使用arguments、super、new.target、也不能用作构造函数,也没有prototype属性。
6:所有的函数对象都会暴露一个只读的name属性,多数情况下,这个值就是一个字符串化的变量名,就是函数名的字符串化表示。如果函数没有名称,它会是空字符串。如果是使用Function构造函数创建的,则是anonymous。
7:在函数中,arguments对象是一个类数组对象,可以使用中括号语法去访问函数调用时传入的参数。arguments.length属性可以获取到调用时一共传入了多少个参数。
8:修改arguments对象的值会自动同步到对应的命名参数,但是这不意味着他们都访问的是同一个内存地址,它们在内存中还是分开的,只不过会保持同步而已。而且这种同步是单向的,修改命名参数的值不会影响arguments对象中相应的值。
9: 函数调用时如果只传了一个参数,然后把arguments[1]设置为某个值,那么这个值并不会反应到第二个命名参数,因为arguments对象的长度是根据传入的参数的个数,而不是定义函数时给出的命名参数确定的。

function a(n, c) {
  arguments[1] = 10;
  return n + c
}
console.log(a(10)); // NaN
console.log(a(10, 8)); // 20 

// 发现一个问题,修改命名参数的值也会更新arguments对应的值,例:

function a(n, c) {
  c = 100;
  console.log('c',c); // 100
  console.log('a1', arguments[1]) // 100
  return n + c
}
console.log(a(10, 8));

10: 函数的默认参数只有在函数被调用时才会求值,不会在函数定义时求值,而且,计算默认值的函数只有在调用函数但未传相应参数时才会被调用。
11:函数参数时按照顺序初始化的,所以后定义默认值的参数可以先引用先定义的参数。反过来则会报错。
12: 参数只存在自己的作用域中,它们不能引用函数体的作用域。
13: 函数声明和函数表达式的区别,JavaScript引擎在任何代码执行之前,会先读取函数声明,并在执行上下文中生成函数定义。而函数表达式必须等到代码执行到它那一行,才会在执行上下文中生成函数定义。函数声明会提升,函数表达式则不会。
14:arguments.callee属性指向arguments对象所在函数的指针。
15:在标准函数中,this引用的是把函数当成方法调用的上下文对象。
16:在箭头函数中,this引用的是定义箭头函数的上下文。
17: 在严格模式中访问arguments.callee和arguments.caller会报错,在非严格模式下访问arguments.caller始终是undefined。在严格模式下不可以给函数的caller属性赋值,否则会报错。
18:ECMAScript中的函数始终可以作为构造函数实例化一个新对象,也可以作为普通函数被调用,ES6新增了检测函数是否使用new关键字调用的new.target属性。如果函数是正常调用的,则其值是undefined,如果是用new构造函数调用的,则new.target将引用被调用的构造函数。
19: 每个函数都有两个属性,length和prototype,其中length属性保存函数定义时的命名参数的个数。prototype属性是保存引用类型所有实例方法的地方。
20:apply方法有两个参数一个this值,另一个是数组或者arguments对象。
21:call方法有多个参数,一个是this值,剩下的可以是一个或多个参数,参数是逐个传递的。
22:使用call和apply的好处是可以将任何对象设置为任意函数的作用域。
23:bind方法会创建一个新的函数实例,其this值会被绑定到传给bind方法的对象。
24:闭包指的的是那些引用了另一个函数作用域中变量的函数。