• 变量,作用域知识


    1、基本类型和引用类型的值

    ECMAscript的变量和其他语言变量有所不同,其为松散型变量,每个变量只是一个占位符而已。变量可能包含两种类型的值

    一种为基本类型的值,在内存中占据固定大小,保存在栈内存中,简单的数据段,string,number,Boolean,null,undefined,

    一种为引用类型的值,指可能为多个值构成的对象,object,保存在堆内存中;引用类型的值保存在内存中的对象,js不允许直接操控内存中的对象。实际操控对象的引用来操控对象,其变量是个指向该对象的指针。

    1.1动态的属性

    当操作变量时候,对于引用类型的值,可以添加属性,方法,可以改变,删除属性和方法;但是对于基本类型的值,就不可以添加属性(虽然不会产生错误)

            //基本类型的值
            var name="double";
            name.age=27;
            name.sex="man";
            console.log(name.age)     //undefined
    
    
            //引用类型的值
            var person=new Object();
            person.name="double";
            person.age=20;
            person.sex="man"
            console.log(person.name)   //double

    1.2复制变量的值

    对于基本类型来说,复制变量值就是clone了,两个变量完全独立,没有任何关系

    对于引用类型来说,复制变量值实际复制的只是个指针,指向存储在堆中的一个对象,两个变量实际将引用同一个对象改变任意一个,都将改变

            //对于基本类型,复制之后完全独立,没有关系
            var one=12;
            var two=one;
            one=13;
            console.log(one)    //13
            console.log(two)    //12
        
            //对于引用类型,变量名只是指针,引用的是同一个对象    
            var obj1=new Object();
            var obj2=obj1;
            obj1.name="double";
            obj1.sex="man";
            obj2.sex="woman";
            console.log(obj2.name)   //double
            console.log(obj1.sex)    //woman

    1.3传递参数

    js中所有函数参数都是按值传递的。

    把函数外部的数复制给参数,基本类型的传递如同基本变量的复制一样,而引用类型的传递如同引用变量的复制一样。但是参数是按值传递的。

    在传递基本类型值时,被传递的值复制给局部变量(也就是命名参数),仅仅是值得修改。

    在传递引用类型值时,将这个值再内存中的地址复制给局部变量,因此这个局部变量的变化会反映在函数的外部。

            function add(num){
                 num+=10;
                 return num;
            }
            var count=20;
            var result=add(count)
            console.log(count)     //20
            console.log(result)    //30
    
            function setName(obj){
                obj.name="double";   //函数的内部,obj和person引用的是同一对象,即使参数是按值传递的
                obj=new Object();    //即使函数内部被修改,但是原有的引用未改变,重写obj时,变量的引用只是局部变量,函数执行完毕立刻被销毁
                obj.name="single";
            }
            var person=new Object();
            setName(person);
            console.log(person.name);   //double

    1.4检测类型

    检测基本数据类型时,一般用操作符typeof,但是当类型为null和对象时,检测的都是object;检测引用类型,想知道某个类型的对象用instanceof操作符。

            var person=new Object();
            var colors=[];
            var pattern=/d/;
            console.log(person instanceof Object)  //都是true
            console.log(colors instanceof Array)
            console.log(pattern instanceof RegExp)
    当instanceof检测引用类型和Object构造函数时,始终会返回true;而检测基本数据类型则为false

    2、执行环境和作用域

    执行环境(execution context)定义了变量或者函数有权访问的其他数据,定义了它们各自的行为。每个环境中都有一个与之相关的变量对象,环境中定义的所有变量和函数都保存在这个对象中,全局执行环境是最外围的执行环境,即window对象。某个执行环境中所有代码执行完毕后,该环境被销毁。

    执行环境有全局环境和函数环境两种

    当代码在一个环境中执行,会创建变量对象的一个作用域链,以保证对执行环境有权访问的所有变量和函数的有序访问.

            var color="blue";
            function change(){
                 var anotherColor="red";
                 function changeAgain(){
                      var tempColor=anotherColor;
                      anotherColor=color;
                      color=tempColor; 
                     console.log(tempColor)       //red
                     console.log(anotherColor)    //blue
                     console.log(color)           //red
                  }
                     // console.log(tempColor)    访问不到
                     console.log(anotherColor)    //red
                     console.log(color)           //blue
                     changeAgain()
              }
                     // console.log(tempColor)    访问不到
                     // console.log(anotherColor) 访问不到
                     console.log(color)           //blue
                     change()

    内部环境可以通过作用域链访问所有的外部环境,而外部环境不能访问内部环境的任何变量和函数

    2.1延长作用域链

    有些语句可以在作用域链的前端临时加个变量对象,代码执行后就移除,

    try-catch语句中的catch块;with语句。

    2.2没有块级作用域

    js中是没有块级作用域的,所以if内的变量就是window对象下的;for循环的变量同是

           if(true){
                   var color="red";
           }
           console.log(color) //red
    
           for(var i=0;i<10;i++){
                  console.log(i)  //0-9
           } 
           console.log(i)      //10

    声明变量

    涉及到var操作符,有var声明则是局部变量,没有则是全局变量,在函数的执行环境内,外部是访问不到的 。

    查询标识符

    在某个环境中引用一个标识符,必须通过搜索来确认该标识符代表着什么,先从自身环境搜索,然后沿着作用域链向上溯回查询,一旦找到就OK。

           var color="red";
           function getColor(){
                   return color
           }
           console.log(getColor())  //red

    基础不牢,地动山摇

  • 相关阅读:
    图标字体IcoMoon 使用
    JS 寻找孩子并打印路径
    为什么要用on()而不直接使用click
    setTimeout 虚假的“异步”
    解决Ajax.BeginForm还是刷新页面的问题
    .net生成Excel,并下载
    C#判断文件是否正在被使用
    sql为数字添加千分位(也就是钱的格式)
    HotelIInventory项目小结
    一步一步实现FormsAuthentic验证登录
  • 原文地址:https://www.cnblogs.com/iDouble/p/8372310.html
Copyright © 2020-2023  润新知