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

简介: 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>
相关文章
|
11天前
|
自然语言处理 JavaScript 前端开发
[JS]知识点
本文介绍了JavaScript中的多个重要知识点,包括ES6、严格模式、类与对象、解构、跨域问题及入口函数等。文章通过详细示例和推荐的外部资源,帮助读者更好地理解和应用这些概念。内容持续更新中,适合初学者和进阶开发者参考。
10 2
[JS]知识点
|
11天前
|
机器学习/深度学习 自然语言处理 前端开发
前端神经网络入门:Brain.js - 详细介绍和对比不同的实现 - CNN、RNN、DNN、FFNN -无需准备环境打开浏览器即可测试运行-支持WebGPU加速
本文介绍了如何使用 JavaScript 神经网络库 **Brain.js** 实现不同类型的神经网络,包括前馈神经网络(FFNN)、深度神经网络(DNN)和循环神经网络(RNN)。通过简单的示例和代码,帮助前端开发者快速入门并理解神经网络的基本概念。文章还对比了各类神经网络的特点和适用场景,并简要介绍了卷积神经网络(CNN)的替代方案。
|
10天前
|
移动开发 前端开发 JavaScript
前端实训,刚入门,我用原生技术(H5、C3、JS、JQ)手写【网易游戏】页面特效
于辰在大学期间带领团队参考网易游戏官网的部分游戏页面,开发了一系列前端实训作品。项目包括首页、2021校园招聘页面和明日之后游戏页面,涉及多种特效实现,如动态图片切换和人物聚合效果。作品源码已上传至CSDN,视频效果可在CSDN预览。
17 0
前端实训,刚入门,我用原生技术(H5、C3、JS、JQ)手写【网易游戏】页面特效
|
11天前
|
JavaScript 前端开发 中间件
JS服务端技术—Node.js知识点
本文介绍了Node.js中的几个重要模块,包括NPM、Buffer、fs模块、path模块、express模块、http模块以及mysql模块。每部分不仅提供了基础概念,还推荐了相关博文供深入学习。特别强调了express模块的使用,包括响应相关函数、中间件、Router和请求体数据解析等内容。文章还讨论了静态资源无法访问的问题及其解决方案,并总结了一些通用设置。适合Node.js初学者参考学习。
28 1
|
19天前
|
监控 前端开发 JavaScript
React 静态网站生成工具 Next.js 入门指南
【10月更文挑战第20天】Next.js 是一个基于 React 的服务器端渲染框架,由 Vercel 开发。本文从基础概念出发,逐步探讨 Next.js 的常见问题、易错点及解决方法,并通过具体代码示例进行说明,帮助开发者快速构建高性能的 Web 应用。
52 10
|
16天前
|
数据采集 存储 JavaScript
如何使用Puppeteer和Node.js爬取大学招生数据:入门指南
本文介绍了如何使用Puppeteer和Node.js爬取大学招生数据,并通过代理IP提升爬取的稳定性和效率。Puppeteer作为一个强大的Node.js库,能够模拟真实浏览器访问,支持JavaScript渲染,适合复杂的爬取任务。文章详细讲解了安装Puppeteer、配置代理IP、实现爬虫代码的步骤,并提供了代码示例。此外,还给出了注意事项和优化建议,帮助读者高效地抓取和分析招生数据。
如何使用Puppeteer和Node.js爬取大学招生数据:入门指南
|
19天前
|
存储 JavaScript 前端开发
JS的ES6知识点
【10月更文挑战第19天】这只是 ES6 的一些主要知识点,ES6 还带来了许多其他的特性和改进,这些特性使得 JavaScript 更加现代化和强大,为开发者提供了更多的便利和灵活性。
15 3
|
30天前
|
Web App开发 JavaScript 前端开发
Node.js:JavaScript世界的全能工具
Node.js:JavaScript世界的全能工具
|
30天前
|
JSON JavaScript 前端开发
使用JavaScript和Node.js构建简单的RESTful API服务器
【10月更文挑战第12天】使用JavaScript和Node.js构建简单的RESTful API服务器
17 0
|
存储 JavaScript 前端开发
JavaScript与PHP中正则
有个在线调试正则的工具,点击查看工具。下面的所有示例代码,都可以在codepen上查看到。
JavaScript与PHP中正则