批改状态:合格
老师批语:
实例:
function getName(username) {return "hello " + username;}console.log(getName("小柯"));
立即执行函数( IIFE ): 阅后即焚,不会给全局环境带来任何的污染,用来创建临时作用域
实例:
(function (username) {console.log("hello " + username);})("小柯");
执行方式2: 函数表达式,将匿名函数保存到一个变量中
const getUserName = function (username) {return "hello" + username;};console.log(getUserName("小柯"));
执行方式3: 重点学习,箭头函数 =>
举例:有两个参数的情况
let f1 = function sum(a, b) {return a + b;};console.log(f1(10, 50));
// 使用 箭头函数 来简化匿名函数的声明
// 匿名函数转箭头函数的语法
// 1. 去掉 function ,去掉函数名
// 2. 在参数括号(…) 与 大括号{…} 之间使用 胖箭头 => 连接
// 3.只有一个参数的时候, 参数列表的小括号也可以不要了
// 4.只有一条语句的时候,return和大括号都可以不要了
// 4.只有一条语句的时候,没有参数的情况小括号()必须写上,也可以用”$”或者”_”来代替(特殊情况)
// 6.箭头函数,内部的 this ,是固定的,与它的上下文绑定,不能充当构造函数来创建对象,内部没有 arguments 对象
f2 = (a, b) => {return a + b;};console.log(f2(10, 50));
f3 = username => {return "hello " + username;};console.log(f3("小柯"));
// 没有参数的情况小括号必须写上,也可以用”$”或者”_”来代替(特殊情况)
f4 = c => c * 10;console.log(f4(8));
f5 = () => "小柯语录";console.log(f5());f6 = _ => "小柯语录2";console.log(f6());
// ! 使用场景
// 1. 如果函数需要多次调用, 用命名, 函数表达式, 都可以
// 2. 如果代码要求,必须遵循”先声明, 再调用”的规则, 那就必须用”函数表达式”
// 3. 如果只有完成一些特定的,一次性的工作, 不想留下任何痕迹, 用”IIFE”(立即执行函数), 模块
// 4. 如果调用函数时,需要一个函数充当参数,例如:回调, 就可以使用箭头函数来简化 匿名函数的 声明
//基本类型: 一个变量,就存一个值,变量类型完全由这个值来决定的
// * number, string, boolean, undefined, null
// 不可再分, 是构成其它复合类型的基本单元
// 数值类型;console.log(123456, typeof 123456);// 字符串类型console.log("你好", typeof "你好");//布尔类型console.log(true, typeof true);// undefined类型:已声明未赋值变量的默认值console.log(undefined, typeof undefined);// 未赋值;let a;console.log(a);// 已赋值a = 1;console.log(a);// 对象类型:null是一个空值。console.log(null, typeof null);
// 引用类型: 类似其它语言中的”复用类型”, 集合类型
// 引用类型的数据,由一个或多个, 相同, 或不同类型的”原始类型”的值构造
// 是一个典型的多值类型,一个变量里面对应的是多个值
// * array, object, function(数组,对象,函数)
// 引用类型, 都是对象, 默认返回 object ,函数除外 function
// 声明格式:const arr = [数组成员1,数组成员2];
实例1:
const arr = ["笔记本电脑", 99, 9999];console.log(arr);// 数组的索引是从0开始递增的正整数, 0, 1, 2console.log(arr[0]);console.log(arr[1]);console.log(arr[2]);console.log(arr[3]);//超过了就没有值了,越界了
实例2:
// 判断数组类型的正确方法,记牢console.log(Array.isArray(arr));// 为了更直观的表达数据之间的关联, 可以将 数字索引 换 有意义 的"字符串",以下举例对象字面量const arr1 = { name: "笔记本电脑", num: 99, price: 9999 };console.log(arr1);const arr2 = { 0: "笔记本电脑", 1: 99, 2: 9999 };console.log(arr2);
// 对象 更像一个语义化的数组
// name, num , price叫做属性,类似于变量
实例1:
const obj1 = { name: "笔记本电脑", num: 99, price: 9999 };console.log(obj1);//打印单个属性值,就访问那个语义化的属性名称即可,例如下方console.log(obj1["name"]);console.log(obj1["num"]);console.log(obj1["price"]);// 因为对象的属性名称都是合法的标识符,可以使用点来访问,结果都是一模一样的。例如下方console.log(obj1.name, obj1.num, obj1.price);// 当属性名是非常标识符时, 必须使用数组的方式来访问对象的属性,即外面加中括号,里面加双引号包裹,才可以实现正常访问obj2 = { "my email": "xiaoke@email.cn" };console.log(obj2["my email"]);
// * 对象最吸引人的,不是数组的语义化封装, 而是对数据操作的封装, 方法(语法与函数是一样的)
// 本质上来说, 对象, 就是变量与函数的封装, 内部, 变量改口叫属性, 函数改口叫方法
// 方法(语法与函数是一样的写在内部)
// total:function(){}
实例2:
obj3 = {name: "笔记本电脑",num: 11,price: 9999,// 例如做一个数据格式化的输出,使用方法totaltotal: function () {let str = obj3.name + " 总计: " + obj3.num * obj3.price + " 元 ";return str;},};console.log(obj3.total());//另外的一种写法obj4 = {name: "笔记本电脑",num: 10,price: 9999,// 反引号声明的模板字符串, 可以插入变量/表达式, 这叫"插值"total: function () {let str = `${obj4.name} 总计 ${obj4.num * obj4.price} 元`;return str;},};console.log(obj4.total());obj5 = {name: "笔记本电脑",num: 100,price: 9999,// 应该是对象内部, 使用 当前对象的一个引用, 这样才独立于外部对象,//即”obj4“这个改了一个其他的全部都要改太累了,则使用this来进行代替使用,不论现在改成obj5还是其他参数都不影响输出total: function () {let str = `${this.name} 总计 ${this.num * this.price} 元`;// this: 始终与当前对象绑定(执行环境 / 执行上下文 )// this实际上是 = obj5return str;},};console.log(obj5.total());
// 判断对象类型的更优雅的方法,记牢
//console.log(obj5 instanceof Object);
// 实际工作中, 而是将数组与对象组合起来一起用
// obj6是一个由三个对象构成的数组,外面是数组里面是三个对象
实例3:
obj6 = [{ name: "手机", num: 2, price: 5000 },{ name: "电脑", num: 2, price: 5000 },{ name: "相机", num: 2, price: 5000 },];// 假设这个是购物车,求三个商品的价格总和let res = obj6.map(item => item.num * item.price).reduce((acc, cur) => acc + cur);console.log(res);
// 函数是一种数据类型 , 既是函数也是对象
// 判断是否是函数
console.log(typeof function () {});
// 判断是否是对象
console.log(function () {} instanceof Object);
// 可以当成普通值来使用, 例如充当函数的参数,或者函数的返回值
// 这个很重要, 当参数,就是回调函数, 当返回值,可以创建一个闭包
// js中很多高级应用, 都严重依赖这二个功能, 这也是”高阶函数”的基本特征
// 函数是js的一等公民, 就是通过这个体现的(可以当作函数参数,也可以当作函数的返回值)
实例1:
function f7(callback) {// 参数 callback 是一个函数console.log(callback());}// 调用f1, 匿名函数当成f1的参数f7(function () {return "hello 树先生";});
应用场景2: 函数当成返回值, 这就是闭包
实例2:
function f8() {let a = 1;return function () {//从1 开始就使用a++return (a = a + 1);};}console.log(f8);const f = f8();console.log(f);console.log(f());console.log(f());console.log(f());console.log(f());console.log(f());console.log(f());console.log(f());console.log(f());//* 以上的回调 + 闭包, 都是函数当成"值"来用的经典应用场景// * 下面是函数当成对象来用// * 对象有属性和方法, 当然函数也有属性有方法function xiaoke(a, b) {return a + b;}// 查看函数名console.log(xiaoke.name);// 查看函数需要几个参数console.log(xiaoke.length);//属性可以添加xiaoke.email = "840200456@qq.com";console.log(xiaoke.email);
//对象可以被继承,实现代码复用
// 而JS就是基于原型,实现的继承, 而原型,就是在函数上创建一个普通对象而已
// console.log(xiaoke.prototype);查看函数原型,可忽略
// 后面要学到的类class,构造函数, 他们都是基于”函数是对象”这个前提的
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号