1.利用闭包和作用域消去全局变量
<script>
//魔鬼做法,定义全局变量,污染全局对象,再在函数里面调用。
var gol = 1;
var test1 = fucntion()
{
console.log(gol);
}
//利用闭包与作用域定义全局变量
//gol的作用域在函数内部,返回函数体,优雅地解决了全局的定义
var test2 = function()
{
var gol = 1;
return function()
{
console.log(gol);
}
}(); //注意:赋值时已执行
test1(); //1
test2(); //1
</script>
2.记忆
从以下例子中,可以得出,循环10次求fibonacci数列,函数fibo()调用277次,而优化后只调用27次。
<script>
//递归求出fibonacci数(Ps:数列中,第3个数等于前两个数之和)
//记录执行次数
var record1 = 0;
var fibo = function(n)
{
record1++;
return n < 2 ? n : fibo(n-1) + fibo(n-2);
}
//优化递归性能,添加记忆数组
//记录执行次数
var record2 = 0;
var fibo_improve = function()
{
//记录第n个数的执行结果
var memo = [0,1];
record2 = 1;
//真正的递归函数体
var fibo = function(n)
{
record2++;
var result = memo[n];
//结果不存在,则执行递归
if(typeof result !== 'number')
{
result = fibo(n-1) + fibo(n-2);
//记录结果
memo[n] = result;
};
return result;
};
return fibo;
}();
for(var i = 0;i < 10;i++)
{
console.log(i + ' : ' + fibo(i));
console.log(i + ' : ' + fibo_improve(i));
}
console.log(record1); // 277
console.log(record2); // 27
</script>
3.函数调用4种模式与this绑定
3.1 方法的调用模式
以对象调用方法的形式调用函数,this绑定为对象本身。
<script>
var person = {
name:'King',
saying:function(sentance)
{
//this的绑定为该对象
alert(this.name + ' say: ' + sentance);
}
}
person.saying('123123');
</script>
3.2 构造器调用模式
使用”new“关键字来调用会进行两个操作,一个是建立一个隐型的链接在新对象与对象之间,并且this将会绑定到新对象
<script>
//构造器函数的规范是首字母大写,例如 Array
var Test = function(string)
{
this.status = string;
}
Test.prototype.getStatus = function()
{
return this.status;
}
var t = new Test('ABC');
console.log(t.getStatus()); // ABC
</script>
3.3 函数调用
这算是一个js的设计缺陷,函数绑定的this应该为调用函数的外围函数环境,但是事实上是函数调用直接绑定全局对象。
<script>
var myObject = {
a:1,
b:2
};
//直接调用this
myObject.add = function(){
var helper = function(){
this.value = this.a + this.b;
return this.value;
}
//函数调用时,this绑定到全局对象
return helper();
};
console.log(myObject.add()); //NAN
//优化处理
myObject.add = function(){
var that = this;
var helper = function(){
that.value = that.a + that.b;
return that.value;
}
return helper();
};
console.log(myObject.add()); // 3
</script>
3.4 apply调用
允许自定义this,和参数数组
<script>
var myObject = {
status:'King'
}
var Test = function(string)
{
this.status = string;
}
Test.prototype.getStatus = function()
{
return this.status;
}
console.log(Test.prototype.getStatus.apply(myObject)); //King
console.log(Test.prototype.getStatus()); //undifined
</script>