xone

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

JavaScript作用域

其他语言:以{}代码块作为作用域

python:以函数作为作用域

JavaScript:以函数作为作用域

函数的作用域在函数未被调用之前,已经创建

函数的作用域存在作用域链(一层包一层的函数形成作用域链),并且也是在被调用之前创建。

 - 作用域相关

        1.
            function func(){
                if(1==1){
                    var v= 123;
                }
                console.log(v);
            }
            func()

 运行结果为:123

        2. 
            xo = 'root1';
            function func(){
                var xo = 'root2';
                function inner(){
                    console.log(xo);
                }
                inner();
            }
            func();
            // 作用域链
            // root2

运行结果:root2 

         3. 
            xo = 'root1';
            function func(){
                var xo = 'root2';
                function inner(){
                    console.log(xo);
                }
                return inner;
            }
            result = func();
            result();
            // 作用域链在函数调用之前已经创建,当寻找变量时,根据最开始创建的作用域查找
            // root2

 运行结果:root2

         4. 
            xo = 'root1';
            function func(){
                var xo = 'root2';
                function inner(){
                    console.log(xo);
                }
                xo = 'root3'  // 编译函数时,xo最后的值为'root3',调用inner函数时,找到xo的值为'root3'
                return inner;
            }
            
            result = func();
            result();

运行结果:root3

         5. 
            var xxxx;
            console.log(xxxx);
            
            
            function func(){
                console.log(xo);
                var xo = '123';
                console.log(xo);
            }
            func()
            // 函数内局部变量提前声明(预编译),JavaScript
            1. 预编译:
                var xo  这里的xo是undefined;
            2. 执行

 运行结果:undefined;123

         6.
            function func(num){
                console.log(num); 
                num = 18;
                console.log(num); 

                function num(){
                }
                console.log(num); 
            }
            func(666);
            
            a. 预编译 AO(活动对象)
                先编译参数:
                    AO.num = undefined  //编译形参
                    AO.num = 666      //编译实参
                再编译变量:
                    如果AO中有num,则不做任何操作
                    否则 AO.num = undefined
                最后编译函数:
                    AO.num = function num(){
                             }
            b. 执行

以上代码执行结果:

666
18
function num(){
        }

 

 

         7. 
         
            function func(num){
                console.log(num); 
                function num(){
                }
                console.log(num); 
                num = 18;
                
                console.log(num); 
            }
            func(666);
            
            
            先编译参数:
                    AO.num = undefined
                    AO.num = 666
            再编译变量:
                如果AO中有num,则不做任何操作
                否则 AO.num = undefined
            最后编译函数:
                AO.num = function num(){
                         }

以上代码执行结果:

function num(){
            }
function num(){
            }
18

 

 

          8. 
            function func(){
                console.log(xo);
                var xo = 123;
            }
            func()
            
            编译:
                参数:
                    AO
                变量:
                    AO.xo = undefined
            执行:

- 函数和面向对象相关

      1. 
            function func(arg){
                console.log(this,arg);
            }
            func(18);
            // func.call(window,20);
            // func.apply(window,[30]);
            
            
            (function(arg){
                console.log(this,arg);
            })(123)
            
            在函数被执行时,默认this是代指window对象
            
            function func(){
                window.nn = 'root';
                //nn = 'root';
                this.nn = 'root';
            }
            func()
            console.log(nn);
            
            =====>
                a. 在函数内部,默认都有this变量。默认情况下,执行函数时 this=window
                b. 使用 函数名.call 或者 函数名.apply 可以对函数中的this主动设置值
                
                document.getElementById('id').onclick = function(){
                    // this                
                }
                
                document.getElementById('id').onclick.call(DOM对象)

2. 在JS中没有字典类型

           只有对象伪造成字典形式
           
           var dict = {
                name: 'alex',
                age: 18
           }
           等价于
           var dict = new Object();  # 表示创建空字典
           dict.name = 'alex';
           dict.age = 18;
            
            
           function Foo(name){
                this.Name = name
           }
           
           Foo('root')                   # 当做函数时,this默认是window
           var dict1 = new Foo('root1')    # 当做类时,this是 dict1 同pyself
           // Foo.call(dict1,'root1')
           var dict2 = new Foo('root2')    # 当做类时,this是 dict2
           
           
           ====
           function Foo(name){
                this.Name = name;
                this.Func = function(){
                    console.log(this.Name);
                }
            }
            # 当做函数
            Foo('root1')
            window.Name
            window.Func()

            # 当做类
            obj = new Foo('root2')
            obj.Name
            obj.Func()


            # 直接对象
            dict = {
                Name: 'root3',
                Func: function(){
                    console.log(this.Name);
                }
            }

            # dict = new Object();
            # dict.Name = 'root3';
            # dict.Func = function(){
                    console.log(this.Name);
                }
            dict.Func()
            ==========================》 谁调用函数,this就是谁。 函数()执行时候默认window.函数()
            
            
            谁调用函数,this就是谁。 函数()执行时候默认window.函数()
            每一个函数里都有一个this
            Name = '666';
            var dict = {
                Name: 'root',
                Age: 18,
                Func: function(){
                      // this等于dict  
                      console.log(this.Name);      // root 
                      
                      function inner(){
                          console.log(this.Name);  // 666
                      }
                      window.inner();
                }
            }
            
            dict.Func();
            
            ============================
            谁调用函数,this就是谁。 函数()执行时候默认window.函数()
            每一个函数里都有一个this
            变量查找顺序,作用域链
            Name = '666';
            var dict = {
                Name: 'root',
                Age: 18,
                Func: function(){
                      // this等于dict
                      console.log(this.Name);      // root
                      // that 等于dict
                      var that = this;
                      
                      function inner(){
                          // this=window
                          console.log(that.Name);  // root
                      }
                      window.inner();
                }
            }
            
            dict.Func();

3. 原型

方式一:创建多个对象时,创建了多个this.Func,浪费了内存。

        function Foo() {
            this.name = name;
            
            this.Func = function () {
                console.log(this.name);
            }
        }

 

方式二:原型,创建多个对象时,只会创建一个this.Func

        function Foo(name){
            this.Name = name;
        }
        // 原型
        Foo.prototype = {
            Func: function(){
                console.log(this.Name);
            }
        }

        obj1 = new Foo(1)
     obj1.Func() obj2
= new Foo(2) obj3 = new Foo(3)

 

posted on 2017-03-06 14:23  周小百  阅读(166)  评论(0编辑  收藏  举报