10 函数

反复观看

        1, call 和apply 的区别

                        这两个方法都会以指定的 this 值来调用函数,即会设 置调用函数时函数体内 this                         对象的值。apply()方法接收两个参数:函数内 this 的值和一个参数数 组。第二个参                          数可以是 Array 的实例,但也可以是 arguments 对象。

这里的 callSum()函数必须逐个地把参数传给 call()方法。结果跟 apply()的例子一样。到底是 8 使用 apply()还是 call(),完全取决于怎么给要调用的函数传参更方便。如果想直接传 arguments

对象或者一个数组,那就用 apply();否则,就用 call()。当然,如果不用给被调用的函数传参,则 使用哪个方法都一样。ECMAScript 5 出于同样的目的定义了一个新方法:bind()。bind()方法会创建一个新的函数实例, 其 this 值会被绑定到传给 bind()的对象。比如:

函数声明有会带来变量提升

arguments.callee 就是一个指向正在执行的函数的指针,因此可以在函数内部递归调用,如下 所示:

    function factorial(num) {
      if (num <= 1) {
        return 1;
      } else {

return num * arguments.callee(num - 1);

} }

像这里加粗的这一行一样,把函数名称替换成 arguments.callee,可以确保无论通过什么变量 调用这个函数都不会出问题。因此在编写递归函数时,arguments.callee 是引用当前函数的首选。

不过,在严格模式下运行的代码是不能访问 arguments.callee 的,因为访问会出错。此时,可 以使用命名函数表达式(named function expression)达到目的。比如:

    const factorial = (function f(num) {
      if (num <= 1) {
        return 1;
      } else {

return num * f(num - 1);

} });

这里创建了一个命名函数表达式 f(),然后将它赋值给了变量 factorial。即使把函数赋值给另 一个变量,函数表达式的名称 f 也不变,因此递归调用不会有问题。这个模式在严格模式和非严格模式 下都可以使用。

使用var 和不使用var的区别,如果不使用var的话,比如 num = 1; 这其实是一个赋值操作,那么就会在当前作用域链中寻找这个变量,如果找不到,就在window上创建一个属性。声明变量和创建对象属性这两者之间是有区别的。

即便如此,可能你还是很难明白"变量声明"跟"创建对象属性"在这里的区别。事实上,Javascript 的变量声明、创建属性以及每个 Javascript 中的每个属性都有一定的标志说明它们的属性----如只读(ReadOnly)不可枚举(DontEnum)不可删除(DontDelete)等等。

由于变量声明自带不可删除属性,比较 var num = 1 跟 num = 1,前者是变量声明,带不可删除属性,因此无法被删除;后者为全局变量的一个属性,因此可以从全局变量中删除

setTimeout就一定在设置的时间里执行吗,不一定,只是在设定的时间里,将setTimeout的回掉函数放到消息队列里,至于什么时候,回掉函数从队列里弹出来,这个时间是不可控制的。

try catch 不能捕获promise.reject的错误,因为 promise.reject是异步的,而try catch 是同步的。我们看到的异常,是消息队列在抛出的错误。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值