• javascript第二章--变量、作用域和内存问题


    ① 基本类型和引用类型的值

       javascript中的变量包含两种不同的数据类型的值:基础类型值和引用类型值。 基础类型值指的是简单的数据段,引用类型值指那些可能由多个值构成的对象。 在将一个值赋给变量时,解析器必须确定这个值是基本类型值还是引用类型值。 基本数据类型: String、Number、Boolean、Null、Undefined。 基本数据类型是按值访问的,可以操作保存在变量中的实际的值。 引用数据类型: Object。 引用类型的值是保存在内存中的对象。javascript不允许直接访问内存中的位置,也就是不能直接操作对象的内存空间。在操作对象时,其实是在操作对象的引用而不是实际的对象。所以,引用类型是按引用访问的。

        一. 动态的属性

    只有引用类型可以动态地添加属性
    
        var person = new Object();
        person.name = 'dong';
        alert(person.name);  //dong
    
        var person = 'object';
        person.name = 'dong';
        alert(person.name);  //undefined
    

        二. 复制变量值

       在从一个变量向另外一个变量复制基本类型值和引用类型值也存在不同。

       复制基本类型的值,会在变量对象上创建一个新值,然后把该值复制到为新变量分配的位置上,这两个变量可以互相操作而不会相互影响。如图:

       复制引用类型的值,同样也会将存储在变量对象中的值复制一份放到为新变量分配的空间中。不同的是,这个值的副本实际上是一个指针,而这个指针指向存储在堆中的一个对象。复制操作结束后,两个变量实际上将引用同一个对象。改变一个变量,会影响另一个变量。如图:

        三. 传递参数

       javascript中函数的参数都是按值传递的。javascript高级程序设计中写了3处代码用来理解

      1.
        function addTen (num) {
            num += 10;
            return num;
        }
        var count = 20;
        var result = addTen(count);
        alert(count);  //20
        alert(result); //30
    
      2.
        function setName (obj) {
            obj.name = 'Nicholas';
        }
        var person = new Object();
        setName(person);
        alert(person.name);  //Nicholas
      
      3.
        function setName (obj) {
            obj.name = 'Nicholas';
            obj = new Object();
            obj.name = 'Greg';
        }
        var person = new Object();
        setName(person);
        alert(person.name);  //Nicholas
    

       怎么说呢,对于第三个代码,它这样写是为了证明对象是按值传递的。按书中理解的,如果是按引用传递的,那么object = new Object();obj.name='Greg';后person就会自动被修改为指向其name属性值为'Greg'的新对象。这点是非常奇怪的,函数内obj明明是重新引用了一个新的局部对象,这个对象在函数执行完毕后会立即摧毁,那结果person.name为Nicholas没问题啊,这也解释不清引用类型是按值传递的哈................,要不就是我太蠢不能够理解.................(¯ ∩  ¯)。

       改:向林大佬请教了一波后,我终于充分理解了:大佬,就是大佬.......添上大佬的代码注释(林大佬的博客:http://www.cnblogs.com/jarjune/

        var person = new Object();// 地址A
        setName(person);// 传递地址给obj,obj的地址是A
        在setName函数里
        obj.name = 'Nicholas'; // A地址的name是Nicholas
        obj = new Object(); // obj的地址是B
        obj.name = 'Greg'; // B地址的name是Greg
        alert(person.name)// A的name
    

        四. 检测类型

       检测一个变量是否是基本类型,typeof操作符为最佳工具;检测一个变量是什么类型的对象,可以用instanceof操作符,如果用来检测基本类型,都返回false,包括null。

    ② 执行环境及作用域

       作用域就是变量和函数的可访问范围,在javascript中,变量的作用域有全局作用域和局部作用域两种。

        一. 全局作用域

       在代码中任何地方都能访问到的对象拥有全局作用域,有3种情形拥有全局作用域。

        1. 最外层函数和在最外层函数外面定义的变量拥有全局作用域。
        2. 所有未定义直接赋值的变量自动声明为拥有全局作用域。
        3. 所有window对象的属性拥有全局作用域。
    

        二. 局部作用域

       和全局作用域相反,局部作用域一般只在固定的代码片段内可访问到,最常见的例如函数内部,也有人把这种作用域称为函数作用域。

        三. 作用域链

    ③ 垃圾收集

  • 相关阅读:
    由高度场求法线
    unity中的透视投影矩阵
    bindpose定义
    blinn-phong高光反向穿透问题
    fft ocean注解
    理顺FFT
    unity, 在image effect shader中用_CameraDepthTexture重建世界坐标
    unity, ComputeScreenPos 作用
    Lambert漫反射的BRDF
    VC++ MFC获取对话框上控件的位置
  • 原文地址:https://www.cnblogs.com/wuzhendong/p/7839074.html
Copyright © 2020-2023  润新知