跳到主要内容

函数表达式

函数声明提升

会在代码执行前先读取函数声明,但是不会读取函数表达式。

同环境下不要尝试重载一个函数声明,即使是控制语句中。

递归

递归中要注意函数的变化 :

function factorial(num) {
if (num <= 1) {
return 1
} else {
// 使用 arguments.callee 而不是 factorial
// 能防止在外界将 factorial 设为 null 而引发的错误
return num * arguments.callee(num - 1)
}
}

当然也可以使用命名函数表达式来避免错误:

var factorial = (function f(num) {
if (num <= 1) {
return 1
} else {
return num * f(num - 1)
}
})

闭包

闭包的作用域链会携带包含他的函数的作用域,所以要注意闭包的使用量,避免占用过多内存。

需要注意的是,闭包里携带的是指向变量的指针,而非单纯的变量值:

function createFunction() {
var result = new Array

for (var i = 0; i < 10; i += 1) {
result[i] = function() {
return i
}
}
return result
}

alert(createFunction()[4]()) // 10 ,因为函数结束后 i = 10

当然也有解决方案:

function createFunction() {
var result = new Array

for (var i = 0; i < 10; i += 1) {
result[i] = function(num) {
return function() {
return num
}
}(i)
}
return result
}

模仿块级作用域

可以用这种方式实现块级作用域:

// 这样形式的块级表达式的上面一条语句需要分号
(function() {
// 这里是块级作用域
})()

或者这样来摆脱括号:

_ = function() {
// 这里是块级作用域
}()

私有变量

通过声明变量,而非使用 this

function MyObject() {
// 使用 var 而非 this.
var privateValue = 0

// 访问方法
this.getPrivateValue = function() {
return privateValue
}
}

静态私有变量

将静态私有变量放在块级作用域里实现访问阻塞:

_ = function() {
var name = ""

Person = function(value) {
name = value
}

Person.prototype.getName = function() {
return name
}

Person.prototype.setName = function(value) {
name = value
}
}()

模块模式

可以这样实现一个单例:

var application = function() {
var components = new Array()

components.push(new BaseComponent())

return {
getComponentCount: function() {
return components.length
},
registerComponent: function(component) {
if (typeof component == "object") {
components.push(component)
}
}
}
}