JavaScript入门第十九章(JS补充知识点)(完结)

1.引用类型与值类型区别

  • 引用类型:复杂数据类型,object(Object、Array、Date、RegRex、function)

  • 值类型:基本数据类型,五种:string number boolean undefined null。

    • 1.变量只能访问栈中的空间

    • 2.如果是引用类型(复杂数据类型),则将保存在堆中,而栈中存储的是这个数据的地址。

    • 3.如果是值类型(基本数据类型),则数据保存在栈中(数据比较小,读取比较快捷方便)

    • 4.内存主要有两部分:栈与堆

  <script>
       /* 引用类型:array,obejct    数据存储在堆中,地址存储在栈中
           值类型:string number boolean undefined null 数据存储在栈中
  
           区别:值类型:栈中存储的是数据,变量赋值时拷贝的是数据,修改拷贝后的数据不会对原数据造成影响
           引用类型:栈中存储的是地址,变量赋值时拷贝的也是地址,修改拷贝后的数据会对原数据造成影响

       */

      // 1.值类型:拷贝的是数据
      var num1 = 10;
      var num2 = num1;					// 将num1的数据拷贝一份保存到num2中
      num2 = 100;
      console.log ( num1, num2 );		// 修改num2不会对num1造成影响
  
      // 2.引用类型:  拷贝的是地址
      var arr1 = [10,20,30,40,50];
      var arr2 = arr1;					// 将arr1的地址拷贝一份保存到num2中
      arr2[0] = 100;
      console.log ( arr1, arr2 );		// 修改arr2会对arr1造成影响
  </script>

 

2.共享引用

  • JS中实际对象传值不是真正的引用传值(传地址),而是传递引用的副本(call by sharing):按共享传递

  • 对象赋值的本质是对象引用的副本

    • 保存副本的对象如果是对对象本身进行操作:那么就是引用(操作原对象)

    • 保存副本的对象如果是重新赋值:那么就重新开辟存储空间

	// 1.对象共享传递
    var obj1 = { name: '我是本体' };

    // 2.对象引用(共享)
    var obj2 = obj1;
    var obj3 = obj1;

    // 3.引用的改变效果:如果操作的是对象本身(属性或者方法)那么操作的是原对象obj1,如果把保存引用的变量赋值其他任何类型数据,那么都会重开内存(不影响obj1)
    obj2.name = '我是新本体';	// obj2操作的是obj1本身的对象,所以修改是共用的(不开辟新空间)
    console.log(obj1);          // {name: "我是新本体"}
    obj3 = 1;					// obj3独立开辟内存空间保存1,与obj1和obj2不再有关联
    console.log(obj1);          // {name: "我是新本体"}

	// 共享引用:共享引用是JS中复杂数据类型的本质传递方式而已

 

3.基本包装类型

  • 本身是基本数据类型,但是在执行代码的过程中,可以调用相关的属性和方法

  • JS中有三种基本包装类型

    • Number

    • String

    • Boolean

 /*
      // 问题:为什么num是一个基本数据类型,可以像对象一样调用方法呢?
  
      // 基本数据类型
      var num = 10;
      console.log ( typeof num );
	  num.toString () ;
      /*
      本质相当于执行了以下代码(JS解释器检测到num调用来toString()方法,所以快速处理了)
      (1) var num = new Number(10);		// 创建对象
      (2) num.toString();				// 调用对象方法
      (3) num = null;					// 删除对象
       */
       
  
      // 对象类型
      var num1 = new Number(10);
  
      /*
      	由于num1本身就是对象类型,所以这里可以直接调用,无需转换
      */
      num1.toString();
      console.log ( num1 );
      console.log ( typeof num1 ); // object
  
  
      var str = '111';
	  str.toString();
      /*
      (1)var str = new String('111');
      (2)str.toString();
      (3)str = null;
       */
      
  
  
      var bol = true;
      bol.toString();
      /*
      (1) var bol = new Boolean(true);
      (2) bol.toString();
      (3) bol = null();
       */

	/*
		基本包装类型和引用类型(new Number()/String()/Boolear()的区别
		1.new产生的对象是长期占用内存,直到脚本结束
		2.基本包装类型属于后台瞬发,用完就销毁了对象:对象 = null
		
		所以:String/Number/Boolean,我们在开发中都是使用基本包装类型
	*/

 

4.数组去重

数组去重:将数组中重复的元素去掉

  • JS数组没有删除具体元素的删除(只能删掉值,删不掉元素的索引),可以使用另外一个结构来进行存储

    • 新数组

    • 新对象

  • JS数组虽然本质可以删除第一个和最后一个元素,可以利用这一特性,交换当前重复的元素到最后,然后进行删除(pop() 或者length--)

  <script>
        var arr = [20, 66, 88, 25, 66, 90, 88, 50]; // [20,25,66,88,90,50]

        //1.排序法

        // // 1.1 对数组排序
        // arr.sort(function(a,b){
        //     return a-b;
        // });
        // console.log(arr);
        // // 1.2 声明空数组存储去重后的数组
        // var newArr = [];
        // //1.3 遍历arr,检查arr[i]与arr[i+1]是否相等
        // for(var i = 0;i<arr.length;i++){
        //     if(arr[i] != arr[i+1]){
        //         newArr[newArr.length] = arr[i];
        //     };
        // };
        // console.log(newArr);




        // 2.假设成立法

        // // 2.1 声明空数组存储去重后的数组
        // var newArr = [];
        // // 2.2 遍历arr,检查arr[i]在不在newArr中
        // for (var i = 0; i < arr.length; i++) {
        //     // 假设成立法 : 某种操作结果只有两种清空。布尔类型存储两种情况。
        //     // 1.声明
        //     var single = true; // 假设不在
        //     // 2.遍历newArr检查 只要与arr[i]相等
        //     for (var j = 0;j<newArr.length;j++) {
        //         if (arr[i] == newArr[j]) {
        //             single = false;
        //             break; // 只要发现重复元素,后面没有必要比较
        //         };
        //     };
        //     // 3. 根据结果实现需求
        //     if (single) {
        //         newArr[newArr.length] = arr[i];
        //     };
        // };

        // console.log(newArr);
        


        // 3.indexOf

        // // 2.1 声明空数组存储去重后的数组
        // var newArr = [];
        // // 2.2 遍历arr,检查arr[i]在不在newArr中
        // for (var i = 0; i < arr.length; i++) {
        //     if(newArr.indexOf(arr[i]) == -1){ // 不在
        //         newArr.push(arr[i]);
        //     }
        // };

        // console.log(newArr);

        // 4.对象法

        var arr = [20, 66, 88, 25, 66, 90, 88, 50];

        /* 核心思路:利用对象的属性名不能重复
            对象的取值赋值特点
                取值 : 存在,取值。 不存在,取undefined
                赋值 : 存在,修改。 不存在,动态添加

        1.声明空对象 : 检查数组元素是否重复 (元素作为属性名,检查对象有没有这个属性)
        2.声明空数组 :存储去重后的数组
        3.遍历arr,检查arr[i]是否重复
         */
         var obj = {};
         var newArr = [];
         for (var i = 0;i<arr.length;i++) {
            // 检查对象有没有 arr[i] 这个属性?
            if (obj[arr[i]] == undefined) { // 未重复 
                newArr.push(arr[i]);
                obj[arr[i]] = 1; // 这里赋值目的是为了下一次取值,不是undefined
            }
         };

         console.log(newArr);
        
        
        // 5.重复元素自我交换删除法
        /*
        	核心思路:判定元素在数组中查到的位置是否是自身(元素是一定能找到的)
        		* 如果是自身:说明当前元素还没有重复
        		* 如果不是自身:说明当前元素在前面已经存在过:交换最后一个元素,然后把最后一个删除
        		
        	步骤:
        	1.遍历数组的每一个元素
        	2.判定当前遍历的元素在当前数组中存在的位置,判定位置是否是当当前自己的位置
        	2.1.是自己位置,说明前面没有重复,忽略
        	2.2.不是自己位置,说明前面已经存在:
        		2.2.1交换最后一个元素过来
        		2.2.2然后删除
        		2.2.3最后一个元素有可能已经与前面重复了,为了不跳过当前新交换的元素,重新从当前元素开始检索	
        */
        arr = [1,1,2,3,5,0,1];
        for (var i = 0; i < arr.length; i++) {
            / /判定当前元素在数组中找出的位置
            if (arr.indexOf(arr[i]) != i) {
                // 说明不是自己:前面已经存在过
                // 交换最后一个元素过来(因为最后一个可以删除
                var temp = arr[i];
                arr[i] = arr[arr.length - 1];
                arr[arr.length - 1] = temp;
			  
                // 删除最后一个元素:两种方式都可以
                // arr.pop();
                arr.length--;
                
                // 最后一个元素有可能已经与前面重复了,所以为了保证安全,被交换过来的元素还要重新经受考验
                i--;
            }
        }
        
        // 注意:以上方式会改变数组中原来元素的顺序位置

    </script>

 上一章:JavaScript入门第十八章(js作用域及变量预解析)

致读者:

 当你学到这里说明你的JavaScript已经入门啦  咱们的JavaScript基础笔记在这里也要画上一个句号了,从明天开始就会进入到我们的webapi的学习了,你准备好了吗?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海海呐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值