js笔记——函数、递归、预编译

函数

  • 函数声明:function 函数名(参数){函数体;}
  • 函数表达式:var 函数名=function(参数){函数体;}
//命名函数表达式定义函数,但是此时只有test表示的是这个函数,abc不是。
var test = function abc() {
    alert('hello world');
}
//匿名函数表达式定义函数 --> 一般说函数表达式指的是这个
var test2 = function () {
    alert('hello world');
}
console.log(test.name); //abc
console.log(test2.name); //test2
  • 命名规则:小驼峰
function theFirstFunc() {
    alert('hello world');
}
//和java、c++输出地址不同,js输出函数体
document.write(theFirstFunc); //function theFirstFunc(){ alert('hello world'); }
  • 形参实参:形参实参传递的个数可以不同,函数会从第一个形参开始往后依次匹配
 var test = function (a, b, c) {
    console.log('a:' + a + ' b:' + b + ' c:' + c);
    console.log(arguments); //arguments -->实参列表
    console.log(test.length); //test.length --> 形参的长度
}
test(1, 2); //a:1 b:2 c:undefined
//Arguments(2) [1, 2, callee: ƒ, Symbol(Symbol.iterator): ƒ]
//3
test(1, 2, 3, 4); //14 a:1 b:2 c:3
//Arguments(4) [1, 2, 3, 4, callee: ƒ, Symbol(Symbol.iterator): ƒ]
//3
//实参a和arguments[0]虽然不是指向同一块地址,
//但是存在映射关系,一个发生变化另一个就会跟着变化
var test = function (a, b) {
    console.log(a);//1
    a = 10;
    console.log(arguments[0]);//10
    arguments[0] = 2;
    console.log(a);//2
}
test(1, 1);
//但是如果实参没有传递,就不会存在映射
var test = function (a, b) {
    console.log(b);//undefined
    b = 10;
    console.log(arguments[1]);//undefined
    arguments[1] = 2;
    console.log(b);//10
}
test(1);
  • 变量作用域:
    定义:变量(变量作用又称上下文)和函数生效(能被访问)的区域
    在<script>标签里面定义的变量为全局变量,在函数里面定义的为局部变量,函数里面可以访问全局变量。
var a = 1;
function test() {
    var b = 2;
    console.log(a); //1
}
test();
console.log(b);//b is not defined

递归

  • 找到规律
  • 找到结束条件
  • 简单应用:求阶乘、求费伯纳西数列

预编译

js执行步骤

  1. 语法分析
  2. 预编译
  3. 解释执行

预编译规则

  1. 函数声明整体提升:函数声明会被提升到逻辑的最前面
test();//test
function test(){
    console.log('test');
}
  1. 变量 声明提升:即变量的声明会被提升到逻辑的最前面,但是变量赋值不会
//如果直接打印一个未声明的变量就会报错
console.log(a);//a is not defined
//但是如果在其他地方给出声明就不会报错
console.log(a);//undefined
var a = 10;
  1. imply global暗示全局变量:即任何变量,如果未经声明就赋值,此变量就为全局对象(window)所有
a = 10;
console.log(a); //10
console.log(window.a); //10
  1. 一切声明的全局变量,全是window的属性 --> window就是全局的域
var a = 10;
// 在全局访问a其实就是访问window.a
console.log(window.a); //10

例子:

function test() {
    //由于赋值操作的顺序为从右向左,在给b赋值的时候b还未声明,所以b被提升为全局对象
    var a = b = 10;
}
test();
console.log(window.a);// undefined
console.log(window.b);// 10

函数预编译详解:

function fn(a) {
    console.log(a); //ƒ a() {}

    var a = 123;
    console.log(a); //123

    function a() {};
    console.log(a); //123

    var b = function () {}
    console.log(b); //ƒ () {}
}
fn(1);
// 函数预编译发生在函数执行的前一刻
// 1. 创建AO对象
// AO{}
// 2. 找到形参和变量声明,将变量和形参名作为AO属性名,值为undefined
// AO{
//     a:undefined
// }
// 3. 将实参值和形参统一
// AO{
//     a:1
// }
// 4. 在函数体里面找函数和变量声明,值赋予函数体
// AO{
//     a:ƒuncrion a() {},
//     b:undefined
// }
// 5. 函数执行

全局预编译详解:

console.log(a);//ƒ a(){}
function a(){}
var a=100;
// 全局预编译发生在全局执行的前一刻
// 1. 创建GO对象(GO === window)
// GO {}
// 2. 找到变量声明,将变量名作为AO属性名,值为undefined
// GO{
//     a:undefined
// }
// 3. 在全局找函数声明,值赋予GO中属性
// GO{
//     a:function a(){}
// }

练习:

global = 100;
function fn() {
    console.log(global);// undefined
    global = 200;
    console.log(global);// 200
    var global = 300;
}
fn();
console.log(global);//100
var global;
// 1. 创建GO对象,找到变量声明和函数表达式
// GO{
//     global:undefined,
//     fn:function fn(){...}
// }
// 2. 开始解析执行 执行到global=100的时候
// GO{
//     global:100,
//     fn:function fn(){...}
// }
// 3. 然后开始执行fn(),创建AO对象,找到变量声明和函数表达式
// AO{
//     global:undefined
// }
// 4. 开始执行函数,打印global,此时为undefined,然后再给global赋值,此时:
// AO{
//     global:200
// }
// 5. 再打印global,它的值为200
// 6. 函数执行完毕再次打印global为AO对象中的global,为100
function test() {
    console.log(b);//  undefined
    if (a) {
        var b = 100;
    }
    console.log(b);//  undefined
    c = 234;
    console.log(c);// 234
}
var a;
test();
a = 10;
console.log(c);// 234
//和上面的例子一样,只不过需要注意的是不要受到if(a){var b = 100;}的干扰,只要是在函数中的变量都会被提升为AO对象里面的属性,此处的b同样会被提升。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值