zoukankan      html  css  js  c++  java
  • js之变量和作用域

    JS的变量和其他语言的变量有很大区别。JS变量时“松散型”的,决定它只是在特定时间用于保存特定的一个名字而已。
    由于不存在变量要保存何种数据类型,变量的值和其数据类型可以在脚本的生命周期内改变

    JS两种数据类型:

       基本类型:(存在栈内存,比如:Number、Null、Boolean、Undefined和String)

       引用类型:(存在堆内存中,Object类型),他的引用地址(指针)存在 栈空间内

    PS(*重点*):

      1、在JS中,string 字符串类型是 值类型(基本类型),不是引用类型;;这是和其他语言不同的地方
      2、基本类型存在栈内存中,他们所占的大小是固定的大小

    1、动态属性

    只有引用类型可以添加动态属性,,基本类型不能添加动态属性原因:因为引用类型存在 堆 内存中,大小不固定,可以动态添加;;但是基本类型存在 栈 内存中,,内存大小固定,所以不能 动态添加属性

    1 var box =new Object();//定义一个引用类型变量
    2 box.Name='小明';
    3 alert(box.Name);
    4 
    5 var num='shit';
    6 num.Name='demo';//基本类型是 不能添加属性的(因为他是存在栈中的,大小是固定的,所以不能添加属性扩展大小)
    7 alert(num.Name);//undefined

    2、赋值对象

    1》基本类型的复制:

    基本类型对象复制,复制的是值。

    2》引用类型的对象复制

     引用类型对象的复制,复制的是地址。

    1 var box =new Object();
    2 box.Name='demo';
    3 
    4 var box2=box;
    5 box2.Name='shit';
    6 alert(box.Name);//shit   因为box和box2指向 堆里 同一个 内存空间,所以 box2改变的是 堆空间中 数据,所以box在取得时候是改变过的数据了

    3、传递参数

    注意:JS中传递参数是 “按值” 传递的,不是 按 “引用” 传递的。

    1 function box(obj){   //记住:这也是按值传递,只不过传递的参数是引用类型,,但是不是按引用传递,,按引用传递,比如c#里的ref 和out/c中&
    2        obj.name='demo';
    3     }
    4 
    5 var p=new Object();
    6 box(p);  //因为 按值传递:传递的是 地址,所以 会为p增加name属性并赋值
    7 alert(p.name);

    PS:传递引用类型的参数和按“引用”传递 是不同的概念。

    4、变量检测

    在之前的学习中,我们知道区分不同类型的数据可以使用 typeof;;但是如果 对 引用类型的数据 在进一步区分(例如:数组、null、正则表达式都是引用类型) 就要使用instanceof

     1 var box1=new Object(); //引用类型
     2 
     3 var box2=/box/; //正则表达式
     4 
     5 var box3=[1,3];//数组
     6 
     7 alert(box1 instanceof Object);  //true
     8 alert(box2 instanceof RegExp);  //true
     9 alert(box3 instanceof Array);  //true
    10 
    11 //PS:instanceof不能对 基本类型进行检测, 因为即使正确 也会返回false
    12 
    13 var box4='demo';
    14 alert(box4 instanceof String); //false
    15 var box5=new String('demo');//使用 new 修饰符的 方式创建的 就可以  使用instanceof  进行检测了
    16 alert(box5 instanceof String);  //true

    5、执行环境及作用域

      执行环境:

         定义变量或函数 有权访问其他数据,决定他们的一切行为。

    全局执行环境被认为最外层的执行环境,在 web 中被认为是 window。

       注意点:

        1》当执行环境中所有的代码执行完成之后,该环境就会被销毁,包括在其中的所有的变量和函数也会被销毁。但是如果是全局环境下,就需要整个程序执行完毕之后,才会销毁(也就是网页关闭之后)

        2》每个执行换进都会有一个对象与之关联对应,就比如全局执行环境对应window。局部执行环境也会(一个函数的{}内部)有一个与之对应的对象,只不过是我们不能访问它,但是 解析器会在处理数据是后台使用它们。

    下面是非常经典的例子,非常容易弄错的:

    1 function a(b){
    2     alert(window.a);
    3     alert(b);
    4        function b(){   //此处的b 既是 当前执行环境的对象的属性,,还是 自己这个函数下的执行环境下的属性;;都能被访问到
    5              alert(b);
    6            }
    7            b();
    8     }
    9 a('shit');

    总结说明:在前面的“Function原型”中提到了,每一个Function函数都是一个对象。。在执行的一瞬间,会产生一个Active Object(简称:AO)的对象,对于全局执行环境就是对应的window,局部执行环境就是AO。所有的变量(包括传进来的参数和自己定义的变量)和函数都会生成为AO的“属性”,所以这就是为什么上面传进来的参数b会被 下面的 函数b 替代掉(因为都是AO的b属性),后面的同名属性会覆盖前面的。

    6、{} 没有起到限制作用域的:if 和 for

    这种时候,就要对使用完的对象 进行 手动的 清除,实现 垃圾回收。

     1 if(true){
     2        var box ='demo';
     3     }
     4 
     5 alert(window.box);// demo  结果: 在 全局的 执行环境下  也能  访问到 box
     6 
     7 box=null;     //将引用释放,等待垃圾回收。
     8 
     9 for(var i=0;i<10;i++){
    10        var num ='shit';
    11     }
    12 alert(i);       //10   结果:  在 全局 执行环境下  能被 访问到
    13 alert(window.num);//shit   结果: 在 全局的 执行环境下 也是能 访问到 num的
    14 
    15 
    16 function sum(num1){
    17        var num2 ='lee';//在 函数内(sum 执行环境下) 用 var  定义的变量时 局部变量
    18        //将  var  去掉 直接定义的  变量时 全局变量
    19        num3 ='xiao';   //这种方式最好不要用,因为 可能会在  下面引发很多问题;;;如果真的想用全局变量,那就直接在外面定义 全局变量就可以了
    20     }
    21     
    22 sum(10);
    23 alert(num2); //报错:num2 is not defined
    24 alert(num3); //xiao
    if和for的演示代码

    7、变量的搜索查询

     沿着 “作用域链” 向上 查询的。

     1 var box ='Lee';
     2 function getBox(){
     3        return box;
     4     }
     5 
     6 alert(getBox());  //Lee
     7 
     8 function getBox2(){
     9        var box ='xiao';
    10        return box;   //在返回 box的值的时候会 向上搜索box的值,现在 SetBox2()作用域内搜索 局部变量,如果没有就 到 SetBox2()的上一层 作用域去寻找,如果一直没有,直到最后带 全局作用域去寻找,如果在找不到就会报错。。只要 找到就 直接返回。
    11     }
    12 alert(getBox2());  //xiao

    8、JS中的垃圾回收

    JS 是 自动进行 垃圾回收的,但是  自己 使用过的 引用类型对象,如果不想使用了,可以 设置成null,那么 一会就会被垃圾回收了,提高性能

    1 var box ={};
    2 box.name='xiaoming';
    3 //以后就不想使用了
    4 box =null;      //  引用被清除了,等待 垃圾回收器 清理
  • 相关阅读:
    jq 获取下一个兄弟原素 下拉箭头旋转
    weui复选框无法传值
    小乌龟 coding 克隆、提交一直提示无权限
    mysql 时间操作
    Mysql表结构导出excel(含数据类型、字段备注注释)
    sql server数据库文件的迁移(mdf&ldf文件)
    thinkphp 5 _initialize 使用问题
    thinkphp5 or
    找实习与校招总结——经验与收获2021
    千兆网数据CRC检验和过滤
  • 原文地址:https://www.cnblogs.com/xiaoxiaogogo/p/3623847.html
Copyright © 2011-2022 走看看