0


JavaScript-变量、作用域与内存(原始值与引用值)

文章目录

ECMAScript 变量可以包含两种不同类型的数据:原始值引用值

在把一个值赋给变量时,JavaScript 引擎必须确定这个值是原始值还是引用值

  • 原始值( primitive value ):最简单的数据,直接存放在变量(栈空间)中

保存原始值的变量是按值访问的,因为我们操作的就是存储在变量中的实际值

  • 引用值( reference value ):多个值构成的对象(保存在内存中的对象),引用类型变量(栈空间)里面存放的是地址,真正的对象实例存放在堆内存中

保存引用值的变量是按引用访问的。JavaScript 不允许直接访问内存位置,因此也就不能直接操作对象所在的内存空间。在操作对象时,实际上操作的是对该对象的引用,而非实际的对象本身。

一、动态属性

  • 原始值不能有属性,原始类型初始化可以使用的只有原始字面量形式
  • 只有引用值可以动态添加后面可以使用的属性
let name1 ='hello';let name2 =newString('nihao');
name1.age =12;
name2.age =13;
console.log(name1.age);//undefined
console.log(name2.age);//13

二、复制值

2.1 原始值复制

  • 在存储时变量中存储的是值本身。通过变量把一个原始值赋值到另一个变量时,原始值会被复制到新变量的位置

下面两个变量是可以独立使用的,互不干扰

let num1 =5;let num2 = num1;

2.2 引用值复制

  • 把引用值从一个变量赋给另一个变量时,存储在变量中的值也会被复制到新变量所在的位置
  • 其不同在于,这里复制的值实际上是一个指针,它指向存储在堆内存中的对象
  • 操作完成后,两个变量实际上指向同一个对象,因此两个变量会相互影响,改变其中一个,另一个也会跟着一起改变
let obj1 =newObject();let obj2 = obj1;
obj1.name ='张三';
console.log(obj2.name);// '张三'

三、传递参数

3.1 原始值作为参数传递

  • 当我们把一个原始值作为参数传递给函数的形参时,其实就是把变量在栈空间的值复制了一份给形参,那么在方法内部对形参做任何修改,都不会影响到外部的变量
functionfn(a){
    a++;
    console.log(a);}let x =10fn(x)// 11
console.log(x);// 10

3.2 引用值作为参数传递

  • 当我们把一个引用值作为参数传递给函数的形参时,其实就是把变量在栈空间里面保存的堆地址复制给了形参,形参和实参其实保存的是同一个堆地址,所以操作的是同一个对象
//当函数内部给 obj 设置了 name 属性时,函数外部的对象也会反映这个变化,//因为 obj 指向的对象是保存在全局作用域的堆内存上functionsetName(obj){
    obj.name ="张三";}let person =newObject();setName(person);
console.log(person.name);// '张三'
  • 当 obj 在函数内部被重写时,它变成了一个指向本地对象的指针,而那个本地对象在函数执行结束时就被销毁了

注意:ECMAScript 中函数的参数就是局部变量

functionsetName(obj){
    obj.name ="张三";
    obj =newObject();
    obj.name ="李四"}let person =newObject();setName(person);
console.log(person.name);// '张三'

四、确定类型( instanceof )

instanceof 用于判断某个对象是否被另一个函数构造

变量( variable ) instanceof  构造函数(constructor) // 返回值为布尔值
  • typeof 操作符适合用来判断一个变量是否为原始类型,但它对引用值的用处不大,因为无论引用的是什么类型的对象,它都会返回 “object”
  • 与 typeof 不同的是,instanceof 要求开发者明确的确认对象为某个特定类型
  • 按照定义,所有引用值都是 Object 的实例,因此通过 instanceof 操作符检测任何引用值和 Object 构造函数都会返回 true
  • 如果用 instanceof 检测原始值,会返回 false,因为原始值不是对象
functionsetName(obj){
    obj.name ="张三";
    obj =newObject();
    obj.name ="李四"}let person =newObject();let person2 ="李四"setName(person);
console.log(person.name);// '张三'
console.log(typeof person);// object
console.log(typeof person2);// string
console.log( person2 instanceofObject);// false
console.log( person instanceofObject);// true

本文转载自: https://blog.csdn.net/weixin_41071974/article/details/123762656
版权归原作者 每天内卷一点点 所有, 如有侵权,请联系我们删除。

“JavaScript-变量、作用域与内存(原始值与引用值)”的评论:

还没有评论