JavaScript变量作用域和内存管理

前言

JS中变量是弱类型,也就是说它的值和类型可以在脚本的生命周期内改变,这时一个强大的特性,但是使用起来也非常容易出现问题。JS中的数据分为基本类型和引用类型,Undefined、Null、Boolean、Number、String这五种就是基本类型,它们都是按值访问的变量,可以操作保存在变量中的实际值;引用类型的值保存在堆内存中的对象里,引用类型在实际操作的是对象引用。

动态属性

对于引用类型的值可以为其添加属性和方法,也可以改变和删除其属性和方法。

var hello = new Object()
hello.id = 10
hello.name = "zhangsan"
hello.print = function() {
     alert(this.id + " " + this.name)
}

hello.print() // 10 zhangsan

delete hello.id
alert(hello.id) // undefined

对于值类型如果也添加属性和方法,这样做并不会出现错误,但是真正操作的时候无法访问到添加的属性和方法。

var hello = "Hello"
hello.id = 10
hello.name = "zhangsan"
hello.print = function() {
     alert(this.id + " " + this.name)
}

alert(hello.print) // undefined
alert(hello.id)  // undefined

typeof操作符能够监测变量的类型,对于任意的Object引用对象都会返回object,JS为了判定引用对象的具体类型使用instanceof操作符,如果用它来测试基本类型直接返回false,对于引用类型会遍历原型链来做识别。

执行上下文和作用域

每个函数都有自己的执行上下文(Execution Context)对象,每个执行上下文对象又包含一个变量对象VO(Variable Object),这个对象专门用来存储执行上下文中的定义的变量、函数和参数,用户编写的代码无法访问这个对象,但解析器在执行过程中会使用它。当执行流执行到一个函数的时候,会创建变量对象的一个作用域链(Scope Chain);如果执行上下文对象是函数,那么函数的活动对象(Active Object)作为变量对象;作用域链下一个变量对象来自包含它的执行上下文变量对象,下一个来自于下一个的执行上下文变量对象,一直延续到最后一个执行上下文的变量对象。

var color = "red"
function print() {
    alert(color)
    var color = "green"
    alert(color)

    num = 100
    alert(num)
}

print() // undefined green 100

alert(num) // 100

使用var声明的变量会自动加入到最接近的环境中去,如果声明时没有var关键字会自动被添加到全局上下文中。var声明变量并且赋值其实是两个步骤,一个是声明另外一个是赋值,声明会被提前到函数开始的地方,赋值操作依然保持在原来的位置,print函数执行的时候它的变量对象VO里包含color的声明,但是还未赋值,这时alert结果就是undefined,之后做了赋值操作结果就是green了,num未使用var声明也就不会加入到print函数的执行环境中而是直接加入到了全局执行环境的变量对象中,后面在全局访问的时候依然能够获取。

从上面的例子可以看出函数的变量对象VO是在函数执行之前初始化的,这也就是为什么在函数中声明的变量和函数会被提前。其实它的声明过程还是分步骤的,主要有三个步骤:声明参数、声明函数、声明变量,其中函数的声明会自动覆盖变量的声明。

function print(num) {
    alert(num) // undefined
    alert(count) // function count() { return 200 }
    var count = 100 // 这个变量声明和函数count声明交换位置结果也不会变化
    function count() {
        return 200;
    }
    alert(count) // 100 
    alert(count()) // 什么都没展示,表明count是一个数值而不是函数

    alert(add) // undefined
    var add = function(x, y) {
         return x + y;
    }
    alert(add) // fuction(x, y) { return x + y; }
}

print()

上面的print函数在执行之前先初始化变量对象VO,VO中声明了参数num,函数count和变量count,但是函数count覆盖了变量count的声明,所以最开始查看count的值是函数声明,接着count=100执行了赋值操作将count从function类型变成了number类型,后面再调用count因为它不是函数无法被调用。特别需要注意的是函数变量和函数声明是不同的,上面的add是一个变量而不是函数声明,最开始的时候它的值就是undefined。

没有块级作用域

前面提到过除了函数有执行上下文,其他的if、switch、for、while语句块都没有执行上下文,这些语句块中声明的变量都会被加入到最近的执行上下变量对象中,这样它们之后的代码块依然能够访问之前的变量,也就说块级作用域并不存在。

 for (var i = 0; i < 10; i++) {

 }
 alert(i) // 10

 if (i == 10) { 
     var hello = "Hello World"
 }

 alert(hello) // Hello World

内存管理

JS中常用的内存垃圾回收主要包括标记清理和引用计数管理,不过引用计数管理会因为循环引用导致对象无法被回收,为了避免这种情况需要在不需要对象的时候将它的引用赋值为空,这样垃圾收集器就能够正确的回收它们了。

深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值