函 数
高内聚 低耦合
函数声明:
1.命名函数表达式(函数声明)
2.匿名函数表达式(函数表达式)—最常用 /*
1. 命名函数表达式
function test( ){
var a=123;
var b=567;
var c=a+b;
document.write(c+" ");
}
test();
2. 匿名函数表达式(最常用)
var test = function (a,b){
var c=a+b;
document.write(c+" hello wrold");}
test(1,2);
// arguments ---------- [1,2] 实参列表
j s 运行三部曲 :
1. 语法分析(通篇扫描,但不执行)
2. 预编译
3. 解释执行
imply global(暗示全局变量 ,全局对象 GO):
imply global(暗示全局变量 ,全局对象 GO):
- 即任何变量,如果变量未经声明就赋值,此变量就为(
window === GO)全局对象所有
var a =123 ===> window{ a : 123} - 任何声明的全局变量也归 window(就是全局的域)所拥有
**预编译 ------ 预编译发生在函数执行前一刻 ( 函数声明整体提升 , 变量 声明提升 )
预编译四部曲:
1. 创建 AO ( GO 、 window )对象 ( Activation Object —— 执行期上下文 )
2. 找形参和变量声明,将变量和形参名作为 AO 属性名,值为 undefined
3. 将实参值和形参同一(把实参赋给形参)
4. 在函数体里面找函数声明,值赋予函数体
例 题
1.百度笔试题
function bar(){
return foo;
foo = 10;
function foo() {}
var foo = 11;
}
console.log(bar());
2.百度笔试题
console.log(bar());
function bar(){
foo = 10;
function foo(){}
ar foo = 11;
eturn foo;
}
作用域 、 作用域链
作用域( [ [ scopel ] ] ):存储了运行期上下文的集合(隐式的属性,我们不可访问,仅供 javascript 引擎存取)
作用域链:[ [ scopel ] ]中所存储的执行期上下文对象的集合,此集合呈链式链接
每次函数执行完成,都要销毁自己的执行期上下文,等待着下一次被执行时,在重新建立
例:
function a(){
function b (){
function c(){}
c(); --------- c执行
}
b(); ------- b执行
}
a(); --------- a执行
a ----- defined ---- a.[[scopel]] ------> 0 : Go
a ----- doing ---- a.[[scopel]] ------> 0 : aAO
1 : GO
-------------------------------------------------------
b ---- defined ---- b.[[scopel]] ------> 0 : aAO
1 : GO
b ----- doing ---- b.[[scopel]] ------> 0 : bAO
1 : aAO
2 : GO
-------------------------------------------------------
c ---- defined ---- c.[[scopel]] ------> 0 : bAO
1 : aAO
2 : GO
c ---- doing ---- c.[[scopel]] ------> 0 : cAO
1 : bAO
2 : aAO
3 : GO
闭 包
当内部函数被保存到外部时,将会产生 “ 闭包 ”,
闭包会导致原有作用域链不释放,造成内存泄漏 。
** 作 用 :**
1. 实现共有变量: eg:函数累加器
2. 可做缓存(存储结构): eg : eater
3. 可实现封装,属性私有化 : eg : Person();
4. 模块化开发,防止污染全局
例: function a(){
var num = 100;
function b(){
num ++;
console.log(num);
}
return b;
}
var demo = a();
demo();
demo();
可实现封装,属性私有化
function Deng (naem, wife) {
var prepareWife = "xaiozhang";
this.name = name;
this.wife = wife;
this.divorce = function (){
this.wife = prepareWife;
}
this.changePrepareWife = function (target){
prepareWife = target;
}
this.sayPerpareWife = function (){
console.log(prepareWife);
}
}
// dneg.prepareWife 是无法直接访问 prepareWife 的值,
// 要访问 必须通过其 内部 sayPerpareWife 函数,实现了属性私有化
var deng = new Deng("dneg","xiaoliu");
用 闭包 可以实现变量私有化,不会污染全局(模块化开发,防止污染全局)
// init ------- 初始化
var name = "laodeng";
var init = ( function () {
var name = "jicheng";
function callName () {
console.log(name);
}
return function () {
callName();
}
} () );
// 两个 name 变量互不影响
init();
console.log(name);
立 即 执 行 函 数 (只执行一次,执行完后函数引用就被释放)
定义: 此类函数没有声明,在执行一次之后立即释放,适合做初始化工作 针对初始化功能的函数
两种写法:
1. ( function() {} () ) ; W3C组织定义 , 建议第一种
2. ( function() {} ) () ; 因为只有 表达式 才能被 执行符号 执行
例:
( function (){
var a = 123;
var b = 345;
console.log(a+b);
}() )
闭 包 例 题
例题:
function test(){
var arr = [ ];
for (var i = 0; i < 10; i++) {
arr[i] = function (){
document.write(i + " ");
}
}
return arr;
}
var myArr = test();for (var j = 0; j < 10; j++) {
myArr [ j ] () ;
}
例题问题解决 ( 只能用立即执行函数解决闭包问题 ):
function test(){
var arr = [ ];
for (var i = 0; i < 10; i++) { // 立即执行函数
( function (j){
arr[j] = function (){
document.write(j + " ");
}
}( i ) );
}
return arr;
}
var myArr = test();
for (var j = 0; j < 10; j++) {
myArr[j]();
}