js分享05-引用数据类型(小白必看)

169 阅读12分钟

引用数据类型

数据类型的区别

存储的区别

  • 基本数据类型:存储在内存中
  • 引用数据类型:将数据本体存在内存中,变量名存储在栈内存中,变量名内部存储着指向堆内存的地址

赋值的区别

  • 基本数据类型:将变量中的数据赋值给另一个变量,赋值后二者毫无关系
  • 引用数据类型:将变量中的地址赋值给另一个变量,赋值后二者同一个地址指向同一个数据

比较的区别

  • 基本数据类型:进行的比较
  • 引用数据类型:进行地址的比较

传参的区别

  • 基本数据类型:将变量内部的数据复制一份, 传递给对应的形参, 所以函数内对这个形参的修改不会影响外界
  • 引用数据类型:将变量内部的地址复制一份, 传给对应的形参, 所以此时函数内形参和变量的内部存储的是同一个地址,所以在函数内部对这个形参的一些修改, 影响外界

函数

  • 概念:存放需要重复多次的代码,随拿随取

函数的定义与调用

  • 1.定义
    • 声明式:function 函数名(){}
      • 在函数定义前或者后都可以调用函数
    • 赋值式:var 函数名 = function () {}
      • 在函数定义后可以调用, 函数定义前不能调用, 因为此时变量内部的值为 undefined
  • 2.调用
    • 函数名(实参/或者不传和
function box() {

            console.log(1 + 1)

        }
  
        // 2. 函数调用

        box()

变量和函数的预解析

变量

  • 变量提升 JS 在运行我们的代码的时候, 会先整体阅读一次我们的代码,读取完毕后, 会将变量的声明(定义)提取到页面的最顶部(JS代码的最顶部) **注意: 提升的只有变量的声明, 没有变量的赋值**
  • 在变量定义前去使用, 得到的是一个 undefined

函数的参数

  • 目的:使函数功能更加灵活
  • 1.形参:函数定义时括号内容,具体的值由实参传递,为传递则为undefined
  • 2.实参:调用时括号内容,将值传递给对应的形参
  • 函数中参数可以有默认值(ES6中新写法)

函数的返回值

  • 概念:每一个函数调用完毕后,都会有一个返回值,每一个函数中, 默认具有一个 return, 在函数内部的最后一行, 默认为 return undefined
  • 需要在函数的内部手动书写一个返回值;return 你需要返回的内容
  • 功能:
    • 具有中断函数的能力,不执行之后的语句
    • 将函数内部的一些值, 返回给函数外部, 让函数外部可以使用
//判断质数
function fn(n) {

            var num = 0;

            for (var i = 2; i < n; i++) {

                if (n % i === 0) {

                    num++

                }

            }

            return num === 0

        }


        var a = prompt()-0

        var res = fn(a)

        console.log(res)

作用域

  • 变量生效的范围

全局作用域

  • 整个 script 标签内部的区域声明的变量就是在全局作用域创建
  • 在全局作用域创建的变量或者函数我们统称为==>全局变量或者全局函数
  • 能在当前代码的所有位置去使用

局部作用域(函数作用域)

  • 在一个函数内部生成的变量就是存在于局部作用域
  • 在局部作用域创建的变量只能在当前作用域内使用

作用域链

  • 每一个作用域上一层会有一个全新的作用域, 每个作用域之间的一个连接, 我们称之为作用域链
规则
查找规则
  • 在一个作用域内查找一个变量, 如果有直接使用, 如果没有会去上一层继续查找
  • 如果找到直接使用, 没有的话继续去上一层查找直到找到了全局作用域, 找到了直接使用, 如果没有找到直接报错

注意: 查找的时候只会层层向上, 不会向下

赋值规则
  • 在一个作用域对一个变量进行赋值, 那么会先在当前作用域内查找变量, 找到直接修改, 如果没有, 会去上一层作用域查找
  • 如果找到直接修改, 没有继续向上, 如果找到了全局作用域还是没有, 那么会在全局作用域创建一个变量, 然后对他进行赋值操作

递归

  • 含义:递归函数就是在一个函数内部调用自身. 循环执行
  • 递归函数有点类似于循环
    • 需要有初始化, 自增, 执行的代码, 判断条件
    • 如果上述的内容缺少, 那么就是一个死递归, 永远不会结束

对象

  • 1.键值对 2.key/value 3.属性名:属性值

对象的操作

创建

字面量构造
  • var obj1 = {} console.log(obj1)
内置构造函数
  • var obj2 = new Object() console.log(obj2)

操作

    • 点语法:对象名.新的属性名 = 对应的属性值 :obj.age = 18
    • 中括号语法:对象名['要新增的属性名'] = 对应的属性值 :obj['age'] = 18
    • 点语法:delete 对象名.要删除的属性名 :delete obj.id
    • 中括号语法:delete 对象名['要删除的属性名'] : delete obj['id']
    • 点语法:对象名.要修改属性值的属性名 = 新的属性值 :obj.name = 'Mary'
    • 中括号语法:对象名['要修改的属性名'] = 新的属性值 : obj['name'] = 'Lisa'
    • 点语法:对象名.要查询的属性名 : console.log(obj.name)
    • 中括号语法:对象名['要查询的属性名'] : console.log(obj['name'])

对象的遍历

        let obj = {
            name: '张三',
            id: 'QF001',
            a:100,
            age:15
        }
        for(let key in obj){
            console.log(obj[key]);
        }

数组

创建

  • 数组内部数据可以不一致,但是一致的数据会方便后续的批量操作

字面量构造

  • var arr1 = {} console.log(arr1)<==使用场景较多

内置构造函数

  • ar arr2 = new Array() console.log(arr2)
  • var arr2 = new Array(10) console.log(arr2)<==创建有长度的数组
  • var arr2 = new Array(10) console.log(arr2)<==创建有内容的数组

长度:length

  • 数组的长度取决于内部有多少元素
  • 下标
  • 从0开始

常用算法

冒泡排序

var a = [20, 17, 16, 4, 9, 3, 7];
        for (var i = 0; i < a.length - 1; i++) {
            for (var j = 0; j < a.length - 1 - i; j++) {
                if (a[j] > a[j + 1]) {
                    var temp = a[j];
                    a[j] = a[j + 1];
                    a[j + 1] = temp;
                }
            }
        }

选择排序

        var a = [20, 17, 16, 4, 9, 3, 7];
        for (var i = 0; i < a.length - 1; i++) {
            var min = i;
            for (var j = i + 1; j < a.length; j++) {
                if (a[j] < a[min])
                    min = j;
            }
            var temp = a[i];
            a[i] = a[min];
            a[min] = temp;
        }
        console.log(a);

数组方法

1.push()

  • 语法:数组. push()
  • 作用:在数组后面追加元素
  • 返回值:数组长度
        console.log(arr.push(9));
        console.log(arr)
        //函数
        function push(a, num) {
            a[a.length] = num;
            return a.length;
        }
        console.log(push(arr, 'we'));
        console.log(arr)

2.pop()

  • 语法:数组. pop()
  • 作用:在数组后面删除元素
  • 返回值:返回删除的元素
        console.log(arr.pop());
        console.log(arr)
        // 函数
        function pop(a) {
            var temp = a[a.length - 1]
            //删除后值没了 长度不变
            delete a[a.length - 1]
            //位置变了 值变了
            a.length -= 1
            return temp;
        }
        console.log(pop(arr))

3.unshift()

  • 语法:数组. unshift()
  • 作用:在数组前面追加元素
  • 返回值:返回数组长度
        console.log(arr.unshift(2));
        console.log(arr)
        // 函数
        var a1 = [1, 2, 3]
        function unshift(a, data) {
            // 一个新的数组来存值
            var b = [data];
            for (var i = 0; i < a.length; i++) {
                b[i + 1] = a[i]
            }
            return {
                arr: b,
                len: b.length
            }
        }
        var r = unshift(a1, 'xixi')
        console.log(r)

4.shift()

  • 语法:数组. shift()
  • 作用:在数组前面删除元素
  • 返回值:返回删除的元素
        var a2 = [ 1, 2, 3]
        console.log(a2.shift());
        function shift(a) {
            var temp = a[0]
            for (var i = 0; i <= a.length - 1; i++)
                a[i] = a[i + 1]
            a.length -= 1
            return temp
        }
        var r2 = shift(a2)
        console.log(r2)

5.reverse()

  • 将数组进行反转
  • 返回值:反转后的数组  会改变原数组
        var arr3 = [1,2,3,4,5,6]
        console.log(arr3.reverse())
        function reverse(a) {
            // 从头开始 到中间停止 前后交换
            for (var i = 0; i < a.length / 2; i++) {
                var temp = a[i]
                a[i] = a[a.length - 1 - i]
                a[a.length - 1 - i] = temp
            }
            return a
        }
        var r1 = reverse(arr3)
        console.log(r1)

6.sort() 排序 // 开发的时候,没有特别要求使用sort // 面试的时候不要一开始说sort

  • 语法一:数组名.sort()
  • 作用:将数组内的数据,转换为字符串,然后一位一位对比
  • 语法二:数组名.sort(function (a,b) { return a- b})
  • 作用:按照数字从小到大
  • 语法三:数组名.sort(function (a,b) { return b - a})
  • 作用:按照数字从大到小返回值:返回一个排序好的数组
        var arr4 = [12, 20, 30, 40, 50, 100]
        console.log(arr4.sort())
        var so =  arr4.sort(function (a,b) { return b - a})
        console.log(so);

7.indexOf()

- 数组.indexOf(数据,从哪个下标开始()第二个参数不传,默认为0) 
- 作用:从左到右的顺序,查找数组中是否包含这个数据 返回值:找到:返回从左到右第一次出现的下标 否则返回-1
var a = [1, 2, 3, 4, 5, 6,1]
        console.log(a.indexOf(2));
        console.log(a.indexOf(7));
        console.log(a.indexOf(5, 1));
        console.log(a.indexOf(2, 7));
       function indexOf(a, data, index = 0) {
            for (var i = index; i < a.length; i++) {
                if (a[i] === data)
                    return i
            }
            return -1
        }
        console.log(indexOf(a, 5,2))//4
        console.log(indexOf(a, 1,2))//6
        console.log(indexOf(a, 2,2))//-1

8.splice() 剪切 or 删除

- 语法一 数组.splice(开始下标数,剪切数量) 
        var arr = [1,2,3,4,5]
        var res = arr.splice(1, 3)
        console.log('剪切到'+res);
  • 语法二:数组.splice(开始下标数,剪切数量,数据一,数据二,数据三...)
  • 返回值:剪切到的内容
        var arr2 = ['jizhixing', 'guoenhui', 'wozuimei']
        var res1 = arr2.splice(1, 1, 'dameinv', 'pianrende')//添加的
        console.log(arr2)
        console.log(res1)//返回删除的
        arr2.splice(0, 0, 'qwertrytu')
        console.log(arr2)
        arr2.splice(5, 0, 'qasadfdgfd')
        console.log(arr2)

9.slice()

- 语法:`数组名.slice('开始下标','结束下标')`
- 作用:将选中的数据复制(包含开始下标不包含结束下标)
- 返回值:以数组形式返回复制的内容
        var arr = [1,2,3,4,5,6,7,8,9,10]
        var res = arr.slice(0,3)
        console.log(res);    //[1, 2, 3]

10.concat()

  • 语法:数组.concat(其他数组)
  • 作用:将其他数组和数组拼接在一起
  • 返回值:拼接好的新数组
        var arr = [100, 200, 300, 400, 100, 500]
        var res = arr.concat([500, 600])
        console.log(arr, res)//[100, 200, 300, 400, 100, 500]   [100, 200, 300, 400, 100, 500, 500, 600]
        var arr2 = ['hello', 'world']
        var res2 = arr.concat(arr2)
        console.log(arr, res2)//[100, 200, 300, 400, 100, 500]  [100, 200, 300, 400, 100, 500, 'hello', 'world']

11.join()

  • 语法:数组.join()
  • 作用:将数组用 连接符 连接成为一个字符串
  • 返回值:连接好的字符串
        var arr = [100, 200, 300, 400, 100, 500]
        var res = arr.join('---')
        console.log(arr, res)//[100, 200, 300, 400, 100, 500]   '100 & 200 & 300 & 400 & 100 & 500'

12.lastIndexOf()

  • 语法:数组.lastIndexOf(数据)
  • 作用:从右向左查找数据在数组中的索引位置
  • 返回值:有该数据,返回第一次出现的索引位置  没有该数据,返回-1
        var arr = [100, 200, 300, 400, 100, 500]
        var res=arr.indexOf(100)
        console.log(res)//0
        var res2=arr.lastIndexOf(100)
        console.log(res2)//4

13.forEach() ==> 遍历数组使用

  • 语法:数组.forEach( function ( item, index, arr ) {} )
    • item:数组中每一个元素
    • index:每一个元素对应的下标
    • origin:原数组 (很少用)
  • 作用:遍历数组
  • 返回值:无
        var arr = [100, 200, 300, 400, 100, 500]
        arr.forEach(function (item, index, arr) {
            console.log(item)
            console.log(index)
            console.log(arr)
            console.log('--------------')
        })

14.map()

  • 语法:数组.map(function (item, index, arr) { })
  • 作用:根据原数组映射一个新数组
  • 返回值:映射后的新数组(需要在函数内部书写return)
        var arr = [100, 200, 300, 400, 100, 500]
        var res = arr.map(function (item, arr) {
            return item * 10
        })
        console.log(arr, res) //[100, 200, 300, 400, 100, 500]    [1000, 2000, 3000, 4000, 1000, 5000]

forEach()和map()语义不同

15.filter()

  • 语法:数组.filter(function (item, index, arr) { }
  • 作用:过滤数组
  • 返回值:过滤后的新数组
        var arr = [100, 200, 300, 400, 100, 500]
        var res = arr.filter(function (item, index, arr) { return item > 100 })
        console.log(res)//[200, 300, 400, 500]
        var res2 = arr.filter(function (item, index, arr) {
            return index > 3
        })
        console.log(res2)// [100,500]

16.every()

  • 语法:数组.every(function (item, index, arr) { })
  • 作用:判断数组是不是每一项都满足条件
  • 返回值:一个布尔
        var arr = [100, 200, 300, 400, 100, 500]
        var res = arr.every(function (item, index, arr){
        return item > 5
        })
        console.log(res)//true

17.some()

  • 语法:数组.some(function (item, index, arr) {})
  • 作用:判断数组是不是某一项满足条件
  • 返回值:一个布尔
        var arr = [100, 200, 300, 400, 100, 500]
        var res = arr.some(function (item, index, arr) {
            return item > 150
        })
        console.log(res)//true

18.reduce()叠加后的效果

  • 语法: 数组.reduce(function (prev, item, index, origin) {}, init)
    • prev: 如果是第一次执行那么可能是 数组[0] 的值, 也有可能是 init 的值,如果是第一次后续的执行, 那么他的值就是上一次遍历返回的结果
    • item: 这个表示的是数组中的每一项
    • index: 这个表示的是每一项对应的索引 // arr: 这个表示的是原数组
    • init:随意传递一个值即可, 只要符合需求
  • 作用: 就是用来叠加的
  • 返回值: 就是叠加后的结果
    • 注意: 以return的形式书写返回条件
        var arr = [1, 2, 3, 4, 5]
        var res = arr.reduce(function (prev, item) {
            return prev *= item
        }, 2)
        console.log(res);//240=2(初始值)*1*2*3*4*5

19.find()用来获取数组中满足条件的第一个数据

  • 语法: 数组名.find(function (item, index, arr) { })
    • item: 这个表示的是数组中的每一项
    • index: 这个表示的是每一项对应的索引
    • arr: 这个表示的是原数组
  • 作用: 用来获取数组中满足条件的数据
  • 返回值: 如果有 就是满足条件的第一个数据;如果没有就是undefined
  • 注意: 要以return的形式执行返回条件
        var arr = [1, 2, 3, 4, 5]
        console.log('原始数组 : ', arr);
        var res = arr.find(function (item) {
            return item > 3
        })
        console.log(res)//4

20.findIndex()用来获取数组中满足条件的第一个数据的下标

  • 语法: 数组名.findIndex(function (item, index, arr) { })
    • item: 这个表示的是数组中的每一项
    • index: 这个表示的是每一项对应的索引
    • arr: 这个表示的是原数组
  • 作用: 用来获取数组中满足条件的数据
  • 返回值: 如果有 就是满足条件的第一个数据下标;如果没有就是-1
  • 注意: 要以return的形式执行返回条件
        var arr = [1, 2, 3, 4, 5]
        console.log('原始数组 : ', arr);
        var res = arr.find(function (item) {
            return item > 3
        })
        console.log(res)//4