arguments关键字
- 有一个关键字(系统生成)叫做arguments,获取所有的实参
- 特点:
- 伪数组:可以当做数组用(用下标访问),使用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
自调用函数
函数
:定义后不会自动执行,一定要调用
自调用函数
:将函数写在另外一个函数的调用位置:函数自己调用自己,开辟作用域,防止全局污染
自调用函数的应用场景
- 代码具有独立性,不与其他代码有任何交集
- 需要保证数据的安全
// 语法:
()(); // 系统只要见到最后一个是括号,
// 认为前面的内容是一个函数,就会执行当前函数
// 将函数写在第一个括号里面即可,函数匿名即可
(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. 回调函数:有名函数
function c(fn) {
fn();
console.log('这是c函数');
}
function a() {
console.log('这是有名函数a');
}
c(a);
- 函数表达式回调
let b = function () {
console.log('这是函数表达式b');
};
c(b);
// 有名回调和函数表达式回调都一样(本质没有区别)
- 匿名回调
c(function () {
console.log('这是匿名回调函数');
});
c(a);
- 有名回调(函数表达式回调)和匿名回调的区别:
- 有名回调:可以多次用,代码会一直在内存存在(优点:多次调用,缺点:代码长期占用内存)
- 匿名回调:只能用1次,如果要再用,代码复制一份(优点:用后即焚,缺点:只能调用1次)
- 一般做回调的时候:都是使用匿名回调
对象
对象作用:一个变量存储多个数据
对象与数组异同点
-
相同点:一个变量存储多个数据
-
不同点:
-
数组有序存储:元素与下标一一对应
-
对象无序存储:属性名与属性值一一对应(键值对)
-
// 对象: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);
对象-补充
- 对象的属性名:没有规定一定是字符串,可以是数字(最终会转变成字符串)
let obj1 = { 0: '安琪拉', 1: '扔个球' };
console.log(obj1);
// 注意事项:如果属性名是数字:一定不能使用.语法
// console.log(obj1.0);
// console.log(obj1[0]);
- 对象的属性名:一般不加引号,但是可以加引号,系统一定是把名字当做字符串
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 : '张三'} );
网友评论