函数内部的属性
arguments
这个属性是一个类数组,它代表着传入函数的所有参数的一个数组的集合。
function test() { return arguments}test(1, '2', true) // [1,'2',true]
也就是我们可以不定义函数传入值,而是采用argument[xxx]来找到对应的传入值。
另外一点,arguments上面同样存在着两个属性。
arguments.callee
这个属性的意义是指向拥有arguments对象的函数,一般情况我们在做递归的时候,我们可以使用它。
我们来个最经典的阶乘的运用来说明这个问题。
function test(num) { if (num <= 1) { return 1 } else { return num * test(num - 1) }}test(5) //120
这里可以使用arguments.callee替代函数内部的递归函数,从而到达一个解耦的作用。
因为,如果我们采用直接递归的方法的话,在下面这种情况的时候,是会出现错误的。
const changeTest = test
test = null
changeTest(4) // 报错!!
因为在内部二次调用test这个函数的时候,它其实已经不再是一个函数了,所以就会报错,
而这个时候就可以使用arguments.callee是解决这种问题的一个好的方法。
function test(num) { if (num <= 1) { return 1 } else { return num * arguments.callee(num - 1) }}
注意事项!!
这里有一个需要注意的地方,就是arguments.callee这个东西,在JS的严格模式下,是不能使用的,会报错!!
caller
这个是调用当前函数的函数引用,例如
function test() { test1()}function test1() { alert(test1.caller) //显示test的代码块}
因为这里也属于函数内部调用自身的情况,所以可以跟上面说的arguments.callee结合起来使用,也就是
function test() { test1()}function test1() { alert(arguments.callee.caller)}
同时如果函数是在全局作用域下面被调用的话,那么caller得到的值就是null。
同时在ES5中,同样还提供了一个属性,也就是arguments.caller 它的存在是为了跟arguments.callee来做一个区分,arguments.caller在取值的过程中,始终都是取得undefinded,这点也是需要注意的一个问题。
this
关于thie指向的问题,有太多文章说明这个了,这里我就不说了。
但是几个提到this就不得不提的,那就是call(),apple(),bind()。
相信这三兄弟大家也是相当的熟悉了,官方对它们的解释是:在特定的作用域中去调用函数。
其实,这三兄弟真正强大的地方,是扩充函数的运行作用域,这个才是三个方法的真正的用法。
例如
color = 'red'const test = { color: 'blue',}function showTest() { return this.color}showTest() // 'red'
showTest.call(test) // 'blue'
showTest.call(this) // 'red'
通过扩充函数的作用域,才是它们的真正的用法。
最后
这是一篇个人的一些学习上面的一些记录,如果有哪里说的不好的地方,欢迎各位老哥指正,如果觉得我写的内容对你有所帮助,求赞!!!!
(第一篇博客,不知道有没有10个赞呀b( ̄▽ ̄)d)