JS学习之旅(六)函数 预编译

  1. 作用域定义:变量(变量作用域又称为上下文)和函数生效(能被访问的区域)
  2. 全局变量 局部变量
  3. 作用域的访问顺序

js运行三部曲

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

// 函数声明整体提升 (函数写在哪里,系统都会把函数提升到函数执行之前)
// 变量 声明提升(在同一作用域内变量写在哪里,系统都会把变量提升到改作用域的最前面),如果没有声明变量,直接用了某个变量,则改变量就会提升到当前作用域的父级作用域中,即window下

	// 函数声明整体提升
	test(1);// 可以执行
	function test(a){
		console.log(a);
	}

	// 变量 声明提升 系统会显var b;
	console.log(b);//undefined
	var b = "123";
	相当于 var b; console.log(b); var b = "123";
	
	//-----------隔开 遇到问题 打印的a为什么
	// 原因, var a ; a = fn ;
	console.log(a);// function () {}
	function a(a){
		var a = 234;
		var a = function () {
		}
		a();
	}
	var a = 123;
		

// --------------------------- 以下为以上产生原因

预编译前奏

  1. imply global 暗示全局变量:即任何变量,如果变量为未经声明就赋值,此变量就为全局对象所有(全局对象window).
    • eg: a = 123;
    • eg: var a = b = 123; // b 为全局变脸 window 下的
  2. 一切声明的全局变量,全都是window的属性
    • eg: var a = 123;===> vindow.a = 123;
	window.a = 10;
	console.log(a);
	a = 10; ---> window.a = 10;

	var b = 123; ---> window.b = 123;
    // window {
    //     b : 123
    // }

    function test(){
        var c = 123;
        console.log(window.c);//undefined
        console.log(c);//123
    }
    console.log(window.c);//undefined
    test();
	

全局对象,即window,window 全局的域;

预编译过程

  1. 函数预编译
    预编译发生在函数执行的前一刻
    函数预编译四部曲
    1. 创建AO对象(Activation Object:执行期上下文)
    2. 形参变量声明,将变量和形参名作为AO属性名,值为undefined(注:如果a没有用var声明,则a为window作用域下,)
    3. 将实参值和形参统一
    4. 在函数体里面找函数声明,值赋予函数体

// 创建AO对象
AO{
//1. 找形参和变量声明,将变量和形参名作为AO属性名,值为undefined
a : undefined,
b : undefined
///2. 将实参值和形参统一
a : 1,
b : undefined
3.在函数体里面找函数声明,将函数的名称放到AO对象的属性名,值赋值成函数体
a : function a() {},
b : undefined,
d : function d() {}
/ 4. 函数执行
// var a = 123;
a : 123,
b : undefined,
d : function d() {}
}

	function fn(a){
		console.log(a);// function a() {}
		
		var a = 123;
		
		console.log(a);	//123
		
		function a() {} // 预编译已经被提升上去了,所以不看了
		
		console.log(a);	// 123
		
		var b = function () {}
		
		console.log(b);	// function () {}
		
		function d() {}

	}
	fn(1);

测试:

	function test(a, b) {
		document.write(a); // 1
		c = 0;
		var c;
		a = 3;
		b = 2;
		document.write(b); // 2
		function b() {}
		function d() {}
		document.write(b); // 2
	}
	test(1);
分析:
AO{
	// 1.
	a : undefined,
	b : undefined,
	c : undefined
	// 2.
	a : 1,
	b : undefined,
	c : undefined
	// 3.
	a : 1,
	b : function b() {},
	c : undefined,
	d : function d() {}
	// 4. 执行
	a : 3,
	b : 2,
	c : 0,
	d : function d() {}
}

	function testO(a, b) {
		console.log(a);// function a() {}
		console.log(b);// undefined
		var b = 234;
		console.log(b);// 234,
		a = 123;
		console.log(a);// 123
		function a() {}
		var a ;
		var b = function () {}
		console.log(a);// undefined
		console.log(b);// function () {}
		
	}
	testO(1);

  1. 全局预编译
    全局预编译三部曲
    1. 创建GO对象(Global Object:)
    2. 找变量为GO的属性,属性值为undefined(如果函数内没有用var定义,则改变量会挂到父级作用域内,即window下)
    3. 找,函数声明为GO的属性,属性赋值为函数

GO === window

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

GO{
	// 1.
	a : function a() {}
	// 2.
	a : 123
}

AO GO TEST ONE

    console.log(window.b)// undefined
    // console.log(b)// 报错
    function test() {
        console.log(a);// undefined
        console.log(window.b);//undefined
        var a = b = 123;
        console.log(a);// 123
		console.log(window.a);// undefined
        console.log(b)// 123
    }
    test();

	GO{
		b : 123;
	}
	AO{
		a : undefined
	}

AO GO TEST TWO 先看AO 如果AO没有 再找GO

    GO{
        // 1.
        test : undefined
        // 2.
        test : function () {}
    }
    AO{
        // 1.
        test : undefined
        // 2.
        test : 1
        // 2.
        test : function () {}
    }

    // 先看AO 如果AO没有 再找GO
    console.log(test);// function () {} 
    function test(test) {
        console.log(test);// function () {}
        var test = 123;
        console.log(test);// 123
        function test(){}
        console.log(test); //123
    }
    test(1);
    var test = 123;
    global = 100;
    function fu() {
        console.log("1---"+global); // undefined
        global = 200;
        console.log("2---"+global);// 200
        var global = 300;
        console.log("3---"+global);// 300
    }
    console.log("4---"+global); // 100
    fu();
    var global ;
    console.log("5---"+global); // 100 GO 先将变量global var global放到GO中,并赋值为 undefined 在赋值为100
    // GO{
    //     // 1.
    //     fu : function () {},
    //     global : undefined
    //     // 2.
    //     fu : function () {},
    //     global : 100
    // }
    //
    // AO{
    //     // 1.
    //     global : undefined
    //     // 2.
    //     global : 200
    //     // 3.
    //     global : 300
    //
    // }
    GO{
        // 1.
        a : undefined,
        test : fn,
        // 2.
        a : 10,
        test : fn,
        c : 234
    }
    function test() {
        console.log("-- 1" +b); // undefined
        if(a){
            var b = 100;
        }
        console.log("-- 2" +b); // undefined
        c = 234;
        console.log("-- 3" +c);// 234
    }
    var a ;
    test();
    AO{
        // 1.
        b : undefined,
        // 2.
        b : undefined,
    }
    a = 10;
    console.log("-- 4" +c); // 234
    

试题

    function bar() {
        return foo;
        foo = 10;
        function foo() {}
        var foo = 11;
    }
    console.log(bar());// function foo() {}
    AO{
		// 1.
		foo : undefined
		// 2.
		foo : function foo() {}
	}
    document.write(bar());//11
    function bar() {
        foo = 10;
        function foo() {

        }
        var foo = 11;
        return foo;
    }
	AO{
		// 1.
		foo : undefined
		// 2.
		foo : function foo() {}
		// 3.
		foo : 10
		// 4.
		foo : 11
	}
    a = 100;
    function demo(e) {
        function e() {}
        arguments[0] = 2;
        document.write("1--" + e + "<br/>");//2 注意arguments的用法
        if(a) {
            var b = 123;
            function c() {}
        }
        var c;
        a = 10;
        var a;
        document.write("2--" + b+ "<br/>");// undefined
        f = 123;
        document.write("3--" + c+ "<br/>");//undefined if内提出来
        document.write("4--" + a+ "<br/>");//10
    }
    var a;
    demo(1);
    document.write("5--" + a+ "<br/>");//100
    document.write("6--" + f+ "<br/>");//123
GO{
	// 1.
	foo : undefined
	// 2.
	foo : bar
}
// 
(window.foo || (window.foo = 'bar'))


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值