zoukankan      html  css  js  c++  java
  • JavaScript 作用域

    JavaScript 作用域

    Javascript 作用域

    一般语言的作用域分两大种 

        1. 以代码块为作用域

        2. 以函数作为作用域

        相对于其他的语言的作用域以代码块为作用域

    例如 JAVA

    public void Func(string v){
            if (1==1){
                string name='Java';
            }
                console.writeline(name);
            }

    如上就会报错:因为是以一个代码块为作用域

    Python : 以函数作为作用域

    def func():
               if 1==:
                    name='alex'
               print(name)
    
             func()

    一:以函数作为作用域(除去let)

    那么JavaScript 是以什么为作用域呢?  

    答案是以函数作为作用域

    例如:

    xo="liang";
         function func(){
            var xo='eric';
            function inner(){
    
                console.log(xo);
    
            }
    
            return inner;
    
         }
        var ret=func()
        ret()

    执行的结果为eric

    那么为什么会执行的为eric 首先是解析func 函数中的代码。执行到function inner 就不会执行了

    就会跳到下return inner 其实ret 就是inner 的内存对象而已了。加了一个()之后就会执行inner 这个函数体

    再来一个例子:

    xo="liang";
         function func(){
            var xo='eric';
            function inner(){
    
                console.log(xo);
    
            }
            xo='tony';
            return inner;
    
         }
        var ret=func()
        ret()

    执行的结果是tony 这个是为什么呢?

    首先我们看看代码 xo 的是赋值了两次。代码是遵循这一条条解析的。到了第二次赋值的时候,xo已经变为 tony 

    那么后面再去执行inner 这个函数的时候执行的结果就是tony 其实可以改一下代码,就看的更清晰了如下:

     xo="liang";
         function func(){
            var xo='eric';
            var xo='tony';
            function inner(){
    
                console.log(xo);
    
            }
            
            return inner;
    
         }
        var ret=func()
        ret()

    改成这个样子之后就更清晰了,

    总结一下 就是函数的作用域 未被调用之前 已经创建了

    还有一个是函数的做用链 比如:

    function func(){
            function inner(){
            }
    }

    其实在调用之前是已经创建好了的作用链 也就是多层函数嵌套

    4.函数内局部变量提前声明
    function func(){
    
            console.log(xxoo);
    
        }

    执行这个时候就会报错

     function func(){
    
            console.log(xxoo);
            var xxoo='print';
    
        }

    但是执行这个时候就不会。因为默认函数内的局部变量就会声明一个undefined 

    就是说,在调用之前,xxxx=undefined 执行 console.log(xxoo); 的时候就会输出一个undefined 

    JavaScript 面向对象

    这个其实是很有意思的

    function foo(){
    
            var x='liang';
         }
    
         fucntion Foo(n){
            this.name=n;
    
         }
    
         var obj = new Foo('we');
         obj.name

    比如上面的一个代码。this就相当于python中的self 

    一、this 代指对象(python self)
    二、创建对象时、new 函数()

    如果面向对象中 foo 函数中还需要嵌套一个函数呢? 那么尝试一下吧

    function Foo(n){
    
            this.name=n;
            this.sayName=function(){
                console.log(this.name);
    
            }
    
         }
    
         var obj1=new Foo('we');
         obj.name
         obj.sayName()

    上面写一个一个sayName 但是我对比了一下python 的一个面向对象的时候才发现这种是不合理的

    如果我有50个对象。那么这个

    function(){
                console.log(this.name);

    这个代码就会在每一个对象里面进行创建。而python 是这个函数就放在类里面的。

    例如这样的

    class School(object):
    
        def __init__(self,name,addr):
            self.name=name
            self.addr=addr
            self.students=[]
            self.teachers=[]
    
        def ronle(self,stu_ojb):
            print("为学生注册 %s"%stu_ojb.name)
            self.students.append(stu_ojb)
    
        def hire(self,teac_obj):
            print("添加新员工%s"%teac_obj.name)
            self.teachers.append(teac_obj)
    
    t1=Teache("liang",22,'F',12000,"Linux")
    t2=Teache("liang2",22,'F',12000,"Python")

    我的t1 和t2 只需要去类里面去找 hire 这个方法。而不是去自己里面去定义这个方法

    那么这个就引出了面向对象里面的原型:

    那么解决的方法如下:

    原型:
    function  Foo(n){
            this.name=n;
    
    
        }
        // Foo 的原型
        Foo,prototype={
            'sayName':function(){
                console.log(this.name)
            }
    
        }
    
        obj1=new Foo('we');
        obj.sayName()
        obj2=new Foo('wee');

    这样就可以直接去类里面去找方法了,不需要在自己定义了。

  • 相关阅读:
    Mysql免安装版脚本
    在防火墙的例外中注册程序(Windows7和XP),改写注册表
    与内存有关的那些事儿(数组分配空间不够,导致缓冲区溢出,从而strcpy会出现异常)
    WPF入门介绍
    vs2008编译QT开源项目--太阳神三国杀源码分析(三) 皮肤
    TOGAF架构开发方法(ADM)之迁移规划阶段
    LoadTest中内存和线程Troubleshooting实战
    BeginInvoke与EndInvoke方法解决多线程接收委托返回值问题
    工具条OutLookBar
    Winform开发框架之通用高级查询模块
  • 原文地址:https://www.cnblogs.com/liang2580/p/9147820.html
Copyright © 2011-2022 走看看