美文网首页
JavaScript基础7-高阶函数 与 对象

JavaScript基础7-高阶函数 与 对象

作者: beizi | 来源:发表于2021-04-06 22:04 被阅读0次

arguments关键字

  1. 有一个关键字(系统生成)叫做arguments,获取所有的实参
  2. 特点:
    • 伪数组:可以当做数组用(用下标访问),使用for循环遍历
    • 在函数外使用会报错
    function max() {
        //  不限参数的max函数
        let m = -Infinity;      // 空擂主思想
        for (let i = 0; i < arguments.length; i++) {
            if (arguments[i] > m) {
                m = arguments[i];
            }
        }
        return m;
    }
    console.log(max(1, 2));
    console.log(max(1, 2, 3, 4));
    // Math.max()
    console.log(Math.max(1, 2, 3, 4, 5));
    // arguments的应用
    // 不确定实参的数量的时候,就用arguments

自调用函数

函数:定义后不会自动执行,一定要调用
自调用函数:将函数写在另外一个函数的调用位置:函数自己调用自己,开辟作用域,防止全局污染

自调用函数的应用场景

  1. 代码具有独立性,不与其他代码有任何交集
  2. 需要保证数据的安全
// 语法:

()();       // 系统只要见到最后一个是括号,
            //  认为前面的内容是一个函数,就会执行当前函数
            //    将函数写在第一个括号里面即可,函数匿名即可

(function(){})()

// 特点:函数里面的代码会自动执行,执行1次(再也无法执行)


(function aa() {
    // console.log('我是自调用函数');
    // 自调用函数的价值
    // 1. 将数据定义在自调用函数内部:
            // 外部无法修改(即使重名也不影响):
            // 保证数据的安全(沙箱:为了保证代码和数据安全)
    let index = 0;
    console.log(index);
    // 2. 自调用函数只会执行1次:不可控(执行完就回销毁内存:不占用内存)
})();
// 自调用函数即使有名:也没有意义,外部不能调用
// aa()         // 提示aa没有定义

// 外部定义变量:也叫index
let index = 1;
console.log(index);         // 1

回调函数

将一个函数当做一个实参,传递给一个函数的形参,然后再被传的函数内部通过形参实现对外部实参的函数调用

function a() {
    console.log('这是a函数');
}
function b() {
    console.log('这是b函数');
}
// fn用来接收一个实参:要求必须是一个函数
function c(fn) {
    // 调用a 或者 b
    // fn:保存的是一个函数,如何触发?加括号
    // 扩展:如何判定一个变量保存的是函数? typeof,得到一个function字符串
    // console.log(typeof fn);

    console.log('这是c函数');
}
c();     // 不给实参:导致形参fn没有赋值:undefined,不能当函数用
// console.log(a);
c(a);
c(b);

回调函数的几种形式

  1. 回调函数:有名函数
// 1. 回调函数:有名函数
function c(fn) {
    fn();
    console.log('这是c函数');
}
function a() {
    console.log('这是有名函数a');
}
c(a);
  1. 函数表达式回调
let b = function () {
    console.log('这是函数表达式b');
};
c(b);
// 有名回调和函数表达式回调都一样(本质没有区别)
  1. 匿名回调
c(function () {
    console.log('这是匿名回调函数');
});
c(a);
  • 有名回调(函数表达式回调)和匿名回调的区别:
    • 有名回调:可以多次用,代码会一直在内存存在(优点:多次调用,缺点:代码长期占用内存)
    • 匿名回调:只能用1次,如果要再用,代码复制一份(优点:用后即焚,缺点:只能调用1次)
    • 一般做回调的时候:都是使用匿名回调

对象

对象作用:一个变量存储多个数据
对象与数组异同点

  • 相同点:一个变量存储多个数据

  • 不同点:

    1. 数组有序存储:元素与下标一一对应

    2. 对象无序存储:属性名与属性值一一对应(键值对)

// 对象:Object,是一种与数组差不多的数据结构(类型),比数组的描述性更强
let arr = ['被子', '盖被子', '国名女神'];
//            0         1        2        
console.log(arr);
// 数组数据具有顺序性,但是没有描述性
// 对象:{字符串下标:值,可以很多,值不限定数据类型}
let obj = {
    name: '被子',
    skill: '盖被子',
    girlfriend: '国名女神'
};
console.log(obj);
// 为了以示区分
// 在数组中:数据叫元素,在对象中:数据叫属性
// 数组中:数据的下标叫下标(索引),在对象中:数据的下标叫做属性名
// 对象访问:与数组一样
console.log(arr['0']);
console.log(obj['name']);  
 // 区别:数组的下标是数字:不要引号(下标本质是字符串:数字与字符串可以自动互转);
// 但是对象的下标是字符串:需要引号
// 但是对象有自己特有的访问方式: .语法  对象.属性名 (属性名不需要加引号)
console.log(obj.skill);
// 数组不行:数字不能用 . 语法
// console.log(arr.2);

对象的CRUD操作

// 定义对象
let obj = {};
// 新增数据:数组法和点语法
obj['name'] = '被子';       // 增加一个name属性
obj.skill = '盖被子';         // .语法属性名不需要引号:增加skill属性
console.log(obj);
// 查看数据:数组法和点语法
console.log(obj.name);          // 取出name属性的值
console.log(obj['skill']);      // 取出skill属性的值
// 扩展:如果访问一个不存在的属性会怎么样?数组有答案:undefined
console.log(obj.boyfriend);     // undefined
// 修改数据:数据法和点语法
obj['name'] = '杯子';
obj.skill = '丢杯子';
console.log(obj);
// 删除数据:数组无法删除,对象可以:delete就是为对象准备的
// delete 对象.属性名 || 对象['属性名']
delete obj.skill;
delete obj['name'];
console.log(obj);

对象-补充

  1. 对象的属性名:没有规定一定是字符串,可以是数字(最终会转变成字符串)
let obj1 = { 0: '安琪拉', 1: '扔个球' };
console.log(obj1);

// 注意事项:如果属性名是数字:一定不能使用.语法
// console.log(obj1.0);
// console.log(obj1[0]);
  1. 对象的属性名:一般不加引号,但是可以加引号,系统一定是把名字当做字符串
let obj2 = { name: '安琪拉', "skill": "扔个球" };
console.log(obj2);
// 访问不受任何影响

复杂对象

  • 一个真实的对象往往都是带着很多数据和结构的
// 复杂对象:对象属性的值不限定数据类型
let obj = {
    // 基础数据类型:常用3种
    name: '被子',
    age: 30,
    single: false,

    // 复合数据类型:数组、对象、函数(方法)
    hobby: ['滑板', '足球', '羽毛球'],
    girlfriend: {
        name: '迪丽热巴',
        age: 18,
        boyfriend: {
            name: '枕头',
            age: 20
        }
    },

    bz: function () {
        console.log('青铜三段');
    }
}
console.log(obj);

// 访问:一层层进去
// 自己名字
console.log(obj.name, obj['name']);

// 数组
console.log(obj.hobby, obj['hobby']);
console.log(obj.hobby[0], obj['hobby'][0]);

// 对象
console.log(obj.girlfriend, obj['girlfriend']);
console.log(obj.girlfriend.boyfriend.name);

// 方法(函数):函数要运行 + ()
console.log(obj.bz);
console.log(obj.bz());
obj['bz']();

对象-内部对象-this

// 对象的访问(属性):无论何时何地,只要访问属性,就必须前面有对象
let obj = {
    heroName: '鲁班七号',
    heroSkill: '飞碟',
    sf: function () {
        // document.write(`${heroName} 释放 ${heroSkill} 技能`);
        // 属性的访问:必须由对象调用
        // 正确访问
        // document.write(`${obj.heroName} 释放 ${obj.heroSkill} 技能`);
        // 上述可以解决问题:对象的名字固定死了,
        //  如果发生外部对象名字的修改,内部代码执行报错
        // JS提供了一个东西:只要有function定义函数,
        //  里面就会产生一个变量:this,代表当前调用当前函数的对象
        document.write(`${this.heroName} 释放 ${this.heroSkill} 技能`);
    }
}

obj.sf();       // obj调用sf方法:里面的this代表obj这个对象

对象的另外一种声明方式

//1.(最常用)简洁方式:   let 对象名 = { 属性名:属性值 }
let p1 = {name:'张三'};       // 语法糖

//2.构造函数:
//构造函数:如果调用一个函数使用了new关键字,这个函数成为构造函数
let p2 = new Object( {name : '张三'} );

相关文章

网友评论

      本文标题:JavaScript基础7-高阶函数 与 对象

      本文链接:https://www.haomeiwen.com/subject/nqmskltx.html