avaScript技巧使用(高级函数)

JavaScript是一种极其灵活的语言,具有多种使用风格。

高级函数

函数是JavaScript中最有趣的部分之一。

本质上是十分简单和过程化的,但也可以是非常复杂和动态的。

此外,由于所有的函数都是对象,所以使用函数指针非常简单

。这些令JavaScript函数不仅有趣而且强大。

以下是几种在JavaScript中使用函数的高级方法

安全的类型检测

JavaScript内置的类型检测机制并非完全可靠。

事实上,发生错误否定及错误肯定的情况也不在少数。

比如说typeof操作符吧,由于它有一些无法预知的行为,经常会导致检测数据类型时得到不靠谱的结果。

Safari在对正则表达式应用typeof操作符时会返回"function",因此很难确定某个值到底是不是函数。

再比如,instanceof操作符在存在多个全局作用域(像一个页面包含多个框架)的情况下,也是问题多多。

在检测某个对象到底是原生对象还是开发人员自定义的对象的时候,也会有问题。出现这个问题的原因是浏览器开始原生支持JSON对象了。因为很多人一直在使用Douglas Crockford的JSON库,而该库定义了一个全局JSON对象。于是开发人员很难确定页面中的JSON对象到底是不是原生的。

解决上述问题的办法都一样。大家知道,在任何值上调用Object原生的toString()方法,都会返回一个[object NativeConstructorName]格式的字符串。

每个类在内部都有一个[[Class]]属性,这个属性中就指定了上述字符串中的构造函数名。

作用域安全的构造函数

构造函数其实就是一个使用new操作符调用的函数。

当使用new调用时,构造函数内用到的this对象会指向新创建的对象实例,

如下面的例子所示:

function Person(name, age, job){ this.name = name; this.age = age; this.job = job;}var person = new Person("Nicholas", 29, "Software Engineer");

ScopeSafeConstructorsExample01.htm

上面这个例子中,Person构造函数使用this对象给三个属性赋值:name、age和job。当和new操作符连用时,则会创建一个新的Person对象,同时会给它分配这些属性。问题出在当没有使用new操作符来调用该构造函数的情况上。由于该this对象是在运行时绑定的,所以直接调用Person(),this会映射到全局对象window上,导致错误对象属性的意外增加。

作用域安全的构造函数在进行任何更改前,首先确认this对象是正确类型的实例。如果不是,那么会创建新的实例并返回。、

关于作用域安全的构造函数。实现这个模式后,你就锁定了可以调用构造函数的环境。如果你使用构造函数窃取模式的继承且不使用原型链,那么这个继承很可能被破坏。

多个程序员在同一个页面上写JavaScript代码的环境中,作用域安全构造函数就很有用了。届时,对全局对象意外的更改可能会导致一些常常难以追踪的错误。除非你单纯基于构造函数窃取来实现继承,推荐作用域安全的构造函数作为最佳实践。

惰性载入函数

因为浏览器之间行为的差异,多数JavaScript代码包含了大量的if语句,将执行引导到正确的代码中。

惰性载入表示函数执行的分支仅会发生一次。

有两种实现惰性载入的方式

第一种就是在函数被调用时再处理函数。在第一次调用的过程中,该函数会被覆盖为另外一个按合适方式执行的函数,这样任何对原函数的调用都不用再经过执行的分支了。

第二种实现惰性载入的方式是在声明函数时就指定适当的函数。这样,第一次调用函数时就不会损失性能了,而在代码首次加载时会损失一点性能。

惰性载入函数的优点是只在执行分支代码时牺牲一点儿性能。至于哪种方式更合适,就要看你的具体需求而定了。不过这两种方式都能避免执行不必要的代码。

函数绑定

另一个日益流行的高级技巧叫做函数绑定。函数绑定要创建一个函数,可以在特定的this环境中以指定参数调用另一个函数。

该技巧常常和回调函数与事件处理程序一起使用,以便在将函数作为变量传递的同时保留代码执行环境。

只要是将某个函数指针以值的形式进行传递,同时该函数必须在特定环境中执行,被绑定函数的效用就突显出来了。

它们主要用于事件处理程序以及setTimeout()和setInterval()。然而,被绑定函数与普通函数相比有更多的开销,它们需要更多内存,同时也因为多重函数调用稍微慢一点,所以最好只在必要时使用。

函数柯里化

与函数绑定紧密相关的主题是函数柯里化(function currying),它用于创建已经设置好了一个或多个参数的函数。函数柯里化的基本方法和函数绑定是一样的:使用一个闭包返回一个函数。两者的区别在于,当函数被调用时,返回的函数还需要设置一些传入的参数。

柯里化函数通常由以下步骤动态创建:调用另一个函数并为它传入要柯里化的函数和必要参数。

curry()函数的主要工作就是将被返回函数的参数进行排序。curry()的第一个参数是要进行柯里化的函数,其他参数是要传入的值。为了获取第一个参数之后的所有参数,在arguments对象上调用了slice()方法,并传入参数1表示被返回的数组包含从第二个参数开始的所有参数。然后args数组包含了来自外部函数的参数。在内部函数中,创建了innerArgs数组用来存放所有传入的参数(又一次用到了slice())。有了存放来自外部函数和内部函数的参数数组后,就可以使用concat()方法将它们组合为finalArgs,然后使用apply()将结果传递给该函数。注意这个函数并没有考虑到执行环境,所以调用apply()时第一个参数是null。

函数柯里化还常常作为函数绑定的一部分包含在其中,构造出更为复杂的bind()函数。

JavaScript中的柯里化函数和绑定函数提供了强大的动态函数创建功能。使用bind()还是curry()要根据是否需要object对象响应来决定。

它们都能用于创建复杂的算法和功能,当然两者都不应滥用,因为每个函数都会带来额外的开销。

感谢大家支持,评论或者私我免费白嫖资源

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值