微信小程序项目遇见问题二:变量作用域(续)| 使用data中的数组赋值给变量b,改变b的值,数组改变的解决方法| js基本类型和引用类型的区别| 变量命名冲突

文章目录

      • 一、page外的数据和for循环的循环变量同名
      • 二、for循环外的变量和循环变量同名
      • 三、for循环操作for循环外的变量自加
        • i++
        • +1
        • ++i
        • 总结:
      • 四、for循环操作data中的数组
        • 解决方法:
    • js基本类型和引用类型的区别
      • 1、基本类型:
      • 2.引用类型
        • 1.引用类型的值是可变的
        • 2.引用类型的比较是引用的比较
        • 3.引用类型的值是同时保存在栈内存和堆内存中的对象
      • 五、for循环操作data中的对象

一、page外的数据和for循环的循环变量同名

代码:

var c = 3;

Page({
  data: {
    c:4,
  },
  
  onLoad: function (options) {
    for(let c = 0;c<5;c++){
      console.log('1 '+c);
    }
    for(let c = 0;c<c;c++){
      console.log('2 '+c);
    }
  },
})

运行结果:
在这里插入图片描述

for循环的循环变量,会覆盖page外面的同名变量!

二、for循环外的变量和循环变量同名

代码:

Page({
  data: {
    c:4,
  },
  
  onLoad: function (options) {
    var a = this.data.c;
    for(let a = 0;a<5;a++){
      console.log(a);
    }
  },
})

运行结果:
在这里插入图片描述

for循环的循环变量,会覆盖for循环外面的同名变量!

三、for循环操作for循环外的变量自加

i++

代码:

Page({
  data: {
    c:4,
  },
  
  onLoad: function (options) {
   	var i = this.data.c;
    for(let a = 0;a<5;a++){
      i=i++;
      console.log(i);
    };
    console.log(i);
    console.log(this.data.c);
  },
})

运行结果:
在这里插入图片描述

+1

代码:

Page({
  data: {
    c:4,
  },
  
  onLoad: function (options) {
   	var i = this.data.c;
    for(let a = 0;a<5;a++){
      i=i+1;
      console.log(i);
    };
    console.log(i);
    console.log(this.data.c);
  },
})

运行结果:
在这里插入图片描述

++i
Page({
  data: {
    c:4,
  },
  
  onLoad: function (options) {
   	var i = this.data.c;
    for(let a = 0;a<5;a++){
      i=++i;
      console.log(i);
    };
    console.log(i);
    console.log(this.data.c);
  },
})

运行结果:
在这里插入图片描述

总结:
  1. for 循环里面的自加操作应该用 ++i 或者 +1

  2. i 的变化不会影响data中和其有关的值

四、for循环操作data中的数组

代码:

Page({
  data: {
    arr:[]
  },
  
  onLoad: function (options) {
   	var d = this.data.arr;
    for(let a = 0 ;a<5;a++){
      d.push(a);
      //var d = d.push(a);   报错:d.push not a function
      //d = d.push(a);   报错:d is not defined
      console.log(d);
    };
    console.log(d);
    console.log(this.data.arr);
})

运行结果:
微信小程序项目遇见问题二:变量作用域(续)| 使用data中的数组赋值给变量b,改变b的值,数组改变的解决方法| js基本类型和引用类型的区别| 变量命名冲突_第1张图片

其操作为相互绑定,改变了d也同时改变了data中的arr

解决方法:

菜鸟在网上搜的,那就是你赋值之前先将其这样

var d = JSON.parse(JSON.stringify(this.data.arr));

那么,两者就不会相互干扰!(实测有效),具体原理根据vue推测:
微信小程序项目遇见问题二:变量作用域(续)| 使用data中的数组赋值给变量b,改变b的值,数组改变的解决方法| js基本类型和引用类型的区别| 变量命名冲突_第2张图片
感谢博主:
Gabriel_wei

js基本类型和引用类型的区别

1、基本类型:

我们知道基本的数据类型有:undefined,boolean,number,string,null 按值访问,可操作保存在变量中的实际的值,基本类型值指的是简单的数据段。

基本类型的值是不可变的:

在从一个变量向另一个变量赋值基本类型时,会在该变量上创建一个新值,然后再把该值复制到为新变量分配的位置上

var a = 10;
var b = a; 
a ++ ;
console.log(a); // 11
console.log(b); // 10

此时,a中保存的值为 10 ,当使用 a 来初始化 b 时,b 中保存的值也为10,但b中的10与a中的是完全独立的,该值只是a中的值的一个副本,此后,这两个变量可以参加任何操作而相互不受影响

基本类型的比较是值的比较:只要它们的值相等它们就相等。

还有下面的情况要注意哦!

var a = 1
var b = true;
console.log(a = = b);//true

这是因为= =是比较值相等就相等,而= = =是值和类型都相同时候才为true。其实这是类型转换和 = = 运算符的知识了,也就是说在用= =比较两个不同类型的变量时会进行一些类型转换。像上面的比较先会把true转换为数字1再和数字1进行比较,结果就是true了。 这是当比较的两个值的类型不同的时候= =运算符会进行类型转换,但是当两个值的类型相同的时候,即使是= =也相当于是===。

基本类型的变量是存放在栈区的(栈区指内存里的栈内存),栈区包括了 变量的标识符和变量的值

2.引用类型

引用类型:引用类型有这几种:object、Array、RegExp、Date、Function、特殊的基本包装类型(String、Number、Boolean)以及单体内置对象(Global、Math)。

1.引用类型的值是可变的

当从一个变量向另一个变量赋值引用类型的值时,同样也会将存储在变量中的对象的值复制一份放到为新变量分配的空间中。前面讲引用类型的时候提到,保存在变量中的是对象在堆内存中的地址,所以,与简单赋值不同,这个值的副本实际上是一个指针,而这个指针指向存储在堆内存的一个对象。那么赋值操作后,两个变量都保存了同一个对象地址,则这两个变量指向了同一个对象。因此,改变其中任何一个变量,都会相互影响:

var a = [1,2,3];
var b = a;
b.push(4);
alert(b); //[1,2,3,4]
alert(a); //[1,2,3,4] 对象类型 : 赋值不仅是值的复制,而且也是引用的传递
var a = [1,2,3];
var b = a;
b = [1,2,3,4];//相当于把[1,2,3,4]的地址给了b,使其和a的地址指向不同了,所以不会相互影响!
alert(b); //[1,2,3,4]
alert(a); //[1,2,3]

因此,引用类型的赋值其实是对象保存在栈区地址指针的赋值,因此两个变量指向同一个对象,任何的操作都会相互影响。

2.引用类型的比较是引用的比较
var person1 = '{}';
var person2 = '{}';
console.log(person1 == person2); // true 

上面讲基本类型的比较的时候提到了当两个比较值的类型相同的时候,相当于是用 === ,所以输出是true了。再看看:

var person1 = {};
var person2 = {};
console.log(person1 == person2); // false 

可能你已经看出破绽了,上面比较的是两个字符串,而下面比较的是两个对象,为什么长的一模一样的对象就不相等了呢?

别忘了,引用类型时按引用访问的,换句话说就是比较两个对象的堆内存中的地址是否相同,那很明显,person1和person2在堆内存中地址是不同的:

所以这两个是完全不同的对象,所以返回false;

3.引用类型的值是同时保存在栈内存和堆内存中的对象

javascript和其他语言不同,其不允许直接访问内存中的位置,也就是说不能直接操作对象的内存空间,那我们操作啥呢? 实际上,是操作对象的引用,所以引用类型的值是按引用访问的。准确地说,引用类型的存储需要内存的栈区和堆区(堆区是指内存里的堆内存)共同完成,栈区内存保存变量标识符和指向堆内存中该对象的指针,也可以说是该对象在堆内存的地址。

假如有以下几个对象:

var person1 = {name:'jozo'};
var person2 = {name:'xiaom'};
var person3 = {name:'xiaoq'};

也就是说基本类型在赋值操作后,两个变量是相互不受影响的。

另外需要注意的是:String是一个特殊的基本数据类型。

在很多语言中,String是以对象的形式表示的,但在ECMAScript里没有沿用这种传统,String是当作一种基本数据类型,但它是一个比较特殊的基本类型。

看上去好像String应该做为一个引用类型,可实际上它不是,因为它不是对象。那么看起来它应该是基本数据类型,应该是通值传递的方式来操作。

看下面例子:

var stra = "这是一个字符串";
var strb = stra;
stra = "这是另外一个字符串";
console.log(strb); // 这是一个字符串

上面例子我们看到,仿佛stra通过值传递的方式复制了一份给了strb。当stra改变的时候,strb并没有改变,似乎我们已经可以下结论,String就是个基本数据类型。

可是,因为String是可以任意长度的,通过值传递,一个一个的复制字节显示效率依然很低,看起来String也可以当作引用类型。

看下面例子:

var a = "myobject";
a.name = "myname";
console.log(a.name); // undefined

显示String无法当作一个对象来处理。实际上,javascript里的String是不可以改变的,javascript也没有提供任何一个改变字符串的方法和语法。

var a = "myobject";
a = a.substring(3,5)
console.log(a); // bj

记住这样做,就没有改变String字符串"myobject",只 a 引用了另一个字符串"bj","myobject"被回收了。

所以可以这样讲,String实际上并不符合上面两种数据类型分类,它是具有两方面属性介于两都之间的一种特殊类型。

五、for循环操作data中的对象

代码:

Page({
  data: {
    obj:{
      name1:"wcz",
      "name2":"wcz",
      name3:1,
      name4:[1,2,4],
      "name5":[1,2,4],
      class:"aaaa"
    },
  },
  
  onLoad: function (options) {
   	var a = this.data.obj.name1;
    a = a+"111";
    console.log(a);
    console.log(this.data.obj.name1);
    var a = this.data.obj.name2;
    a = a+"111";
    console.log(a);
    console.log(this.data.obj.name2);
    var a = this.data.obj.name3;
    a = a+1;
    console.log(a);
    console.log(this.data.obj.name3);
    var a = this.data.obj.name4;
    a.push(3);
    console.log(a);
    console.log(this.data.obj.name4);
    var a = this.data.obj.name5;
    a.push(3);
    console.log(a);
    console.log(this.data.obj.name5);
})

运行结果:
微信小程序项目遇见问题二:变量作用域(续)| 使用data中的数组赋值给变量b,改变b的值,数组改变的解决方法| js基本类型和引用类型的区别| 变量命名冲突_第3张图片

使用data中的对象a赋值给另外一个变量b,改变b的值,对象a不变化 (除非是数组,引用类型只有数组较为特殊)

你可能感兴趣的:(微信小程序,data数组被改变,变量的作用域,经验分享,其他,js基本类型和引用类型的区别)