JavaScript会将所有变量和函数声明移动到它的作用域的最前面,这就是所谓的变量提升(Hoisting)。也就是说,无论你在什么地方声明变量和函数,解释器都会将它们移动到作用域的最前面。因此我们可以先使用变量和函数,而后声明它们。
但是,仅仅是变量声明被提升了,而变量赋值不会被提升。如果你不明白这一点,有时则会出错:
- console.log(y); // 输出undefined
- y = 2; // 初始化y
上面的代码等价于下面的代码:
- var y; // 声明y
- console.log(y); // 输出undefined
- y = 2; // 初始化y
为了避免BUG,开发者应该在每个作用域开始时声明变量和函数。
7. 柯里化
柯里化,即Currying,可以是函数变得更加灵活。我们可以一次性传入多个参数调用它;也可以只传入一部分参数来调用它,让它返回一个函数去处理剩下的参数。
- var add = function(x) {
- return function(y) {
- return x + y;
- };
- };
- console.log(add(1)(1)); // 输出2
- var add1 = add(1);
- console.log(add1(1)); // 输出2
- var add10 = add(10);
- console.log(add10(1)); // 输出11
代码中,我们可以一次性传入2个1作为参数add(1)(1),也可以传入1个参数之后获取add1与add10函数,这样使用起来非常灵活。
8. apply, call与bind方法
JavaScript开发者有必要理解apply、call与bind方法的不同点。它们的共同点是第一个参数都是this,即函数运行时依赖的上下文。
三者之中,call方法是最简单的,它等价于指定this值调用函数:
- var user = {
- name: "Rahul Mhatre",
- whatIsYourName: function() {
- console.log(this.name);
- }
- };
- user.whatIsYourName(); // 输出"Rahul Mhatre",
- var user2 = {
- name: "Neha Sampat"
- };
- user.whatIsYourName.call(user2); // 输出"Neha Sampat"
apply方法与call方法类似。两者唯一的不同点在于,apply方法使用数组指定参数,而call方法每个参数单独需要指定:
- apply(thisArg, [argsArray])
- call(thisArg, arg1, arg2, …)
- var user = {
- greet: "Hello!",
- greetUser: function(userName) {
- console.log(this.greet + " " + userName);
- }
- };
- var greet1 = {
- greet: "Hola"
- };
- user.greetUser.call(greet1, "Rahul"); // 输出"Hola Rahul"
- user.greetUser.apply(greet1, ["Rahul"]); // 输出"Hola Rahul"
使用bind方法,可以为函数绑定this值,然后作为一个新的函数返回:
- var user = {
- greet: "Hello!",
- greetUser: function(userName) {
- console.log(this.greet + " " + userName);
- }
- };
- var greetHola = user.greetUser.bind({greet: "Hola"});
- var greetBonjour = user.greetUser.bind({greet: "Bonjour"});
- greetHola("Rahul") // 输出"Hola Rahul"
- greetBonjour("Rahul") // 输出"Bonjour Rahul"
9. Memoization
Memoization用于优化比较耗时的计算,通过将计算结果缓存到内存中,这样对于同样的输入值,下次只需要中内存中读取结果。
- function memoizeFunction(func)
- {
- var cache = {};
- return function()
- {
- var key = arguments[0];
- if (cache[key])
- {
- return cache[key];
- }
- else
- {
- var val = func.apply(this, arguments);
- cache[key] = val;
- return val;
- }
- };
- }
- var fibonacci = memoizeFunction(function(n)
- {
- return (n === 0 || n === 1) ? n : fibonacci(n - 1) + fibonacci(n - 2);
- });
- console.log(fibonacci(100)); // 输出354224848179262000000
- console.log(fibonacci(100)); // 输出354224848179262000000
代码中,第2次计算fibonacci(100)则只需要在内存中直接读取结果。
10. 函数重载
(编辑:ASP站长网)
|