函数提升|this对象|闭包

函数提升|this对象|闭包的理解

读书笔记

@(Javascript)[笔记|后端]

函数声明提升指的是函数在执行代码之前会在作用域链中搜索读取函数声明,这就意味着可以把函数声明写在函数的后面。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
test();
var test = function() {
alert("Hi");
}
//function undefined
test();
function test() {
alert("Hello");
}
//Hello
//test函数声明提升,javascript解释器会把代码中的函数声明提升到作用域顶部
//函数声明优先级高于变量声明
function pric() {
alert(a);
function a() {
alert("function");
}
var a = 1;
}
pric();
function pric() {
alert(a);
var a = 1;
function a() {
alert("function");
}
}
pric();
//立即执行函数,运用块级作用域,函数声明优先级高于变量声明
(function() {
alert(a);
var a = 1;
function a() {
alert("function");
}
})();

函数声明会提升,但是函数表达式不会提升;变量声明也会提升,而变量表达式不会提升,变量表达式在变量没有声明的时候这个变量会被添加到全局作用域中。javascript解析器会率先读取函数声明,并使其在执行任何代码之前可用(可访问)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var b = 1;
console.log(b);
function test(){
b = 2;
console.log(b);
};
test();
console.log(b);
//1 2 2
function func() {
b = 9;
console.log(b);
}
func();
console.log(b);
// 9 9
(function() {
b = 9;
console.log(b);
})();
console.log(b);
// 9 9

递归

  • 代码
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    //典型的递归
    function fun(num) {
    if (num <= 1) {
    return 1;
    } else {
    return fun(num-1) * num;
    }
    }
    //使用arguments.callee()函数来递归本身,不要使用函数名(函数名可能会发生变化)
    function fun(num) {
    if (num <= 1) {
    return 1;
    } else {
    return num * arguments.callee(num-1);
    }
    }
    //or
    var fun = (function f(num) {
    if (num <= 1) {
    return 1;
    } else {
    return num * f(num - 1);
    }
    })

闭包指有权访问另外一个函数作用域的变量的函数,常见的方式是在一个函数中再创建一个函数。闭包中的作用域链是在本函数中的作用域向上一层的函数或者全局作用域连接。闭包可以访问作用域链连接的作用域中的变量和对象。

  • 示例代码
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    var aMessage = "Hello World!";
    var aFunction = function() {
    var anotherMes = "Hello JS!";
    //闭包
    function() {
    alert(anotherMes + "<br />");
    alert(aMessage);
    }
    }
    function createFunctions() {
    var result = new Array();
    for (var i=0;i<10;i++) {
    result[i] = function(num){
    return function() {
    return num;
    };
    }(i);
    }
    return result;
    }

关于this对象

this对象就是在运行时基于函数的执行环境绑定的:在全局函数中,this等于windows,而当函数被当作某个对象的方法调用的时候,this等于那个对象。

1
2
3
4
5
6
7
var name = "windows";
var object = {
name : "object",
getName: function() {
return this.name;
}
}

定义块级作用域->私有作用域

1
2
3
4
5
6
7
8
9
10
11
function outputNumbers(count) {
(function() {
for (var i=0;i<count;i++) {
alert(i);
}
})();
///导致错误,无法访问outputNumbers中的i;
alert(i);
}
//(function(){}();内部定义的变量和对象在函数调用完后销毁)

静态私有变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
(function() {
///私有变量和私有函数
var privateVariable = 10;
function privateFunction() {
return false;
}
//构造函数
myObject = function() {
};
//公有的/特权方法
myObject.prototype.publicMethod = function() {
privateVariable++;
return privateFunction();
}
})
坚持原创技术分享,您的支持将鼓励我继续创作!