声明一个带名字的函数:
// 函数
// 声明函数
let name = "名";
// 声明带名字的函数
function namez(name) {
return name + "字";
}
console.log(namez(name));
示例截图:
声明一个带俩对象名字的函数
// 声明俩参数 参数的值为1和2
let a = 1;
let b = 2;
// 声明名字为namey的函数
function namey(a, b) {
return a + b;
}
console.log(namey(a, b));
声明一个立即执行的函数
// ↓↓↓↓↓↓下面声明一个立即执行的函数↓↓↓↓↓
function namew(wang) {
console.log("我的名字是" + wang);
}
namew("王");
// 上面这是立即执行的,感觉怪怪的,中间一个打印,
console.log(
(function namer(liu) {
return "我的姓名是" + liu;
})("刘")
);
// 尝试了好几遍才对,需要包含在打印的()里面,填写函数namer中liu的值↑
// ↑↑↑↑上面这两种,是阅后即焚的声明函数↑↑↑↑↑
示例截图:
函数表达式;
看代码的意思是,声明一个变量,变量的值是一个函数,如下
const Name = function naMe(dog) {
return "狗英文单词是" + dog;
};
console.log(Name("dog"));
console.log(Name);
// 看到这个符号了吧,以后问别人这是什么意思,一定说是函数表达式 别被笑话
// 上面这种就是声明一个参数,参数的值是一个函数↑↑↑↑↑↑↑↑↑↑
// 匿名函数
let name_a = function (niu) {
return "这是" + niu + "的意思";
};
console.log(name_a("牛牛"));
示例截图:
匿名函数
代码:
// 匿名函数
let name1 = function (Name) {
return '我的名字是' + Name
}
console.log(name1('名字'))
// 箭头函数的简写
let name2 = function (a, b) {
return a + b
}
console.log(name2(1, 2))
// 上面的简写写法为以下
name2 = (a, b) => {
return a + b
}
console.log(name2(2, 3))
// 上面简写的是去掉了functin,在()后面增加了=>胖头鱼符号{}
// 上面是因为声明的参数中的函数有2个值,所以已经是最简方法了,但是当函数内就一个值的时候,还可以继续简写
// 先写一个非简写法
let name3 = function (Name3) {
return Name3
}
console.log(name3('非简写'))
// 下面是简写写法
name3 = (Name3) => {
return Name3
}
console.log(name3('简写'))
// 上面这是就一个值,下面再练习一下
let name4 = function (Name4) {
return '这是非' + Name4 + '写法'
}
console.log(name4('简体'))
name4 = (Name4) => {
return '这是' + Name4 + '写法'
}
console.log(name4('简体'))
// 上面这种写法 还可以简写 因为只有一个参数,且参数仅有一个return返回值简写方式如下
name4 = (Name4) => '这是' + Name4 + '因为就一个return,所以更简单的写法'
console.log(name4('更简单的写法。'))
// 还有,就是没有参数时,一定要把()写上,也就是匿名的时候,简体写法
// 非简体匿名函数先写一段
const name5 = function () {
return '还原后学习到了,是因为返回值里面,也是个空参数 ,且非简体的时候,return这个返回值要写'
}
console.log(name5())
//本来想更新一下的,发现声明用的const,不能再次声明了
let name6 = () =>
'还原后学习到了,是因为返回值里面,也是个空参数 ,且非简体的时候,return这个返回值要写'
console.log(name6())
// 刚刚上面不会写,拿了老师的,还原了一下,看看我是哪里出错的
// let f1 = () => '今天天气很好'
// console.log(f1());
// 还原
// f1 = function () {
// return '今天天气很好'
// }
// console.log(f1())
为了能更好的看懂代码,直接上代码图:
匿名函数:
// 匿名函数
let name_a = function (niu) {
return "这是" + niu + "的意思";
};
console.log(name_a("牛牛"));
// 匿名函数
let name1 = function (Name) {
return "我的名字是" + Name;
};
console.log(name1("名字"));
// 箭头函数的简写
示例截图:
箭头函数
多值函数简写:
let name2 = function (a, b) {
return a + b;
};
console.log(name2(1, 2));
// 上面的简写写法为以下
name2 = (a, b) => {
return a + b;
};
console.log(name2(2, 3));
// 上面简写的是去掉了functin,在()后面增加了=>胖头鱼符号{}
// 上面是因为声明的参数中的函数有2个值,所以已经是最简方法了,但是当函数内就一个值的时候,还可以继续简写
示例截图:
简写之单值简写:
代码部分:
// 先写一个非简写法
let name3 = function (Name3) {
return Name3;
};
console.log(name3("非简写"));
// 下面是简写写法
name3 = Name3 => {
return Name3;
};
console.log(name3("简写"));
// 上面这是就一个值,下面再练习一下
let name4 = function (Name4) {
return "这是非" + Name4 + "写法";
};
console.log(name4("简体"));
name4 = Name4 => {
return "这是" + Name4 + "写法";
};
console.log(name4("简体"));
// 上面这种写法 还可以简写 因为只有一个参数,且参数仅有一个return返回值简写方式如下
name4 = Name4 => "这是" + Name4 + "因为就一个return,所以更简单的写法";
console.log(name4("更简单的写法。"));
示例截图:
匿名函数简写
代码部分:
/ 还有,就是没有参数时,一定要把()写上,也就是匿名的时候,简体写法
// 非简体匿名函数先写一段
const name5 = function () {
return "还原后学习到了,是因为返回值里面,也是个空参数 ,且非简体的时候,return这个返回值要写";
};
console.log(name5());
//本来想更新一下的,发现声明用的const,不能再次声明了
let name6 = () => "还原后学习到了,是因为返回值里面,也是个空参数 ,且非简体的时候,return这个返回值要写";
console.log(name6());
// 刚刚上面不会写,拿了老师的,还原了一下,看看我是哪里出错的
// let f1 = () => '今天天气很好'
// console.log(f1());
// 还原
// f1 = function () {
// return '今天天气很好'
// }
// console.log(f1())
示例截图:
整段代码附上:
// 函数
// 声明函数
let name = "名";
// 声明带名字的函数
function namez(name) {
return name + "字";
}
console.log(namez(name));
// 声明俩参数 参数的值为1和2
let a = 1;
let b = 2;
// 声明名字为namey的函数
function namey(a, b) {
return a + b;
}
console.log(namey(a, b));
function nameq(php) {
return "我爱" + php;
}
// 这里打印的时候要注意,参数的值需要用"",数字好像不需要↓
console.log(nameq("php"));
// ↓↓↓↓↓↓下面声明一个立即执行的函数↓↓↓↓↓
function namew(wang) {
console.log("我的名字是" + wang);
}
namew("王");
// 上面这是立即执行的,感觉怪怪的,中间一个打印,
console.log(
(function namer(liu) {
return "我的姓名是" + liu;
})("刘")
);
// 尝试了好几遍才对,需要包含在打印的()里面,填写函数namer中liu的值↑
// ↑↑↑↑上面这两种,是阅后即焚的声明函数↑↑↑↑↑
// 函数表达式;
// 看代码的意思是,声明一个变量,变量的值是一个函数,如下↓↓↓↓↓
const Name = function naMe(dog) {
return "狗英文单词是" + dog;
};
console.log(Name("dog"));
console.log(Name);
// 看到这个符号了吧,以后问别人这是什么意思,一定说是函数表达式 别被笑话
// 上面这种就是声明一个参数,参数的值是一个函数↑↑↑↑↑↑↑↑↑↑
// 匿名函数
let name_a = function (niu) {
return "这是" + niu + "的意思";
};
console.log(name_a("牛牛"));
// 匿名函数
let name1 = function (Name) {
return "我的名字是" + Name;
};
console.log(name1("名字"));
// 箭头函数的简写
let name2 = function (a, b) {
return a + b;
};
console.log(name2(1, 2));
// 上面的简写写法为以下
name2 = (a, b) => {
return a + b;
};
console.log(name2(2, 3));
// 上面简写的是去掉了functin,在()后面增加了=>胖头鱼符号{}
// 上面是因为声明的参数中的函数有2个值,所以已经是最简方法了,但是当函数内就一个值的时候,还可以继续简写
// 先写一个非简写法
let name3 = function (Name3) {
return Name3;
};
console.log(name3("非简写"));
// 下面是简写写法
name3 = Name3 => {
return Name3;
};
console.log(name3("简写"));
// 上面这是就一个值,下面再练习一下
let name4 = function (Name4) {
return "这是非" + Name4 + "写法";
};
console.log(name4("简体"));
name4 = Name4 => {
return "这是" + Name4 + "写法";
};
console.log(name4("简体"));
// 上面这种写法 还可以简写 因为只有一个参数,且参数仅有一个return返回值简写方式如下
name4 = Name4 => "这是" + Name4 + "因为就一个return,所以更简单的写法";
console.log(name4("更简单的写法。"));
// 还有,就是没有参数时,一定要把()写上,也就是匿名的时候,简体写法
// 非简体匿名函数先写一段
const name5 = function () {
return "还原后学习到了,是因为返回值里面,也是个空参数 ,且非简体的时候,return这个返回值要写";
};
console.log(name5());
//本来想更新一下的,发现声明用的const,不能再次声明了
let name6 = () => "还原后学习到了,是因为返回值里面,也是个空参数 ,且非简体的时候,return这个返回值要写";
console.log(name6());
// 刚刚上面不会写,拿了老师的,还原了一下,看看我是哪里出错的
// let f1 = () => '今天天气很好'
// console.log(f1());
// 还原
// f1 = function () {
// return '今天天气很好'
// }
// console.log(f1())
数据类型:
原始类型:
// 原始类型有以下
// number, string, boolean, undefined, null
// 数字 字符 true false 未定义 空
// 不可再分,是构成其他复合类型的基本单元
查看函数的原始类型:
代码:
console.log(123, typeof 123);
console.log("php", typeof "php");
console.log(true, typeof true);
console.log(undefined, typeof undefined);
console.log(null, typeof null);
示例截图:
上面是老师写的
下面是自己写的
console.log(123, typeof 123);
console.log("php", typeof "php");
// 字符串的时候需要加''引号
console.log(true, typeof true);
console.log(false, typeof false);
console.log(undefined, typeof undefined);
console.log(null, typeof null);
// Object 对象
示例截图:
原始类型的-单值类型:
// 原始类型, 简单类型, 基本类型: 一个变量,存一个值
// 单值类型
let a = 1;
console.log(typeof a);
a = "php";
console.log(typeof a);
// 动态语言: 变量的类型, 由它的值的类型决定
// ! 2. 引用类型
// 引用类型, 都是对象, 默认返回 object ,函数除外 function
// * array, object, function
// 引用类型: 类似其它语言中的"复用类型", 集合类型
// 引用类型的数据,由一个或多个, 相同, 或不同类型的"原始类型"的值构造
// 是一个典型的: 多值类型
示例截图:
刚刚发现,这是老师写的
下面上自己写的
//原始类型 又叫简单类型 单值类型, 比如声明一个变量a a的值=1
let a = 1;
console.log(a);
console.log(a, typeof a);
console.log(typeof a);
// 瞎捣鼓的,老师的是最后这样写法
a = "php";
console.log(typeof a);
a = "";
console.log(typeof a);
// 带了引号就是字符???
// 从上面可以看得出来,变量 a 的类型由 值 a的值来决定的
示例截图:
引用类型:
//引用类型
// 引用类型, 都是对象, 默认返回 object ,函数除外 function
// * array, object, function
// 引用类型: 类似其它语言中的"复用类型", 集合类型
// 引用类型的数据,由一个或多个, 相同, 或不同类型的"原始类型"的值构造
// 是一个典型的: 多值类型
// 这几句话是复制老师的
// // // // // // // // //
// 引用类型之数组类型
// // // // // // // // //
引用类型—数组类型
// 引用类型--数组类型
let sz = ["app", 123, 8888];
// 当前数组排序,我理解为0=app,1=123,2=8888
// 打印一下看看
console.log(sz);
// 打印一下其中的值
console.log(sz[1]);
console.log(sz[2]);
// 打印数组类型的正确方法
console.log(Array.isArray(sz));
// boolean 布尔类型
示例截图:
引用类型—对象类型
示例代码:
//引用类型--对象类型
// 对象类型类似数组类型
let duixiang = { name: "对象", shuzi: 123, shuzi2: 678 };
// 其中对象赋值的时候,要用英文的: ,不能用=
// 下面调佣一下看看
console.log(duixiang["name"]);
// 声明的参数之后,这里需要用[''] 来调佣,注意注意
// 那如果全部调佣改如何调佣呢?看下面
console.log(duixiang);
// 全部调佣不需要再加[]
// 还有另外一种方式调用,例如全部调佣,
console.log(duixiang.name, duixiang.shuzi, duixiang.shuzi2);
// 直接使用变量.对象,来实现,不过这必须是合法对象,非合法对象不适用,例如下面的
let duixiang2 = { "name mingzi": "名字", "name _mz": "名字2", name3: "名字3" };
console.log(duixiang2["name _mz"]);
// 上面是当对象是非法对象时,就必须以数组的方式来访问,必须用 变量[''] 这样
// * 对象最吸引人的,不是数组的语义化封装, 而是对数据操作的封装, 方法(语法与函数是一样的)
// 本质上来说, 对象, 就是变量与函数的封装, 内部, 变量->属性, 函数 -> 方法
// 先声明一个对象
示例截图:
声明一组对象且对象内包含函数:
let os = {
l: "linux",
shuliang: 3,
jiage: 100,
zongji: function () {
// let sl =
// '当前' +
// os.l +
// '数量为' +
// os.shuliang +
// '单价为' +
// os.jiage +
// '总价为' +
// os.shuliang * os.jiage +
// '元'
// return sl
// 需要返回一下 return
// 上面是使用常规方式来实现的,下面是用this来实现
let sl =
"当前" + this.l + "数量为" + this.shuliang + "单价为" + this.jiage + "总价为" + this.shuliang * os.jiage + "元";
return sl;
// 这里的this,相当于声明的那个变量 os的替换变量,当变量os改了之后,并不需要在对象里面的函数里面,挨个更改
},
};
console.log(os.zongji());
// console.log(os['zongji'])这是一个错误的写法,
// 自己试了试,其实可以这么理解,虽然声明的对象里面,如果出现了函数,就以函数的方式调佣,比如console.log(os.zongji())
// 打印上面的数据类型
console.log(typeof os);
// 上面提示的是对象
console.log(os instanceof Object);
// 上面提示的是布尔型
示例截图:
在实际工作中,数组和对象一般都是一起使用,使用演示如下
代码部分:
os = [
{ name: "linux服务器", shuliang: 2, jiage: 100 },
{ name: "win7服务器", shuliang: 2, jiage: 100 },
];
console.log(os[0]);
console.log(os[1]);
// let res = obj.map(item => item.num * item.price).reduce((acc, cur) => acc + cur);
// console.log(res);老师的js,也不知道怎么用
示例截图:
函数
代码部分:
// 函数是一种数据类型 , 并且 还是 对象
console.log(typeof function () {});
// 函数即是函数, 也是对象
console.log(function () {} instanceof Object);
// 这句拿的老师的,
// ! (一) 函数是数据类型的好处?
// 可以当成普通值来使用, 例如充当函数的参数,或者函数的返回值
// 这个很重要, 当参数,就是回调函数, 当返回值,可以创建一个闭包
// js中很多高级应用, 都严重依赖这二个功能, 这也是"高阶函数"的基本特征
// * 应用场景1: 函数做为参数使用, 回调
function f1(hanshu) {
return console.log(hanshu());
}
///应用场景1,没看懂,得后面学习
// 调用f1, 匿名函数当成f1的参数
f1(function () {
return "Hello 朱老师";
});
// 这里挑起了定义的function函数,
//函数是可以当成一个值的!
//既然可以看成一个值,那么就可以当作参数传递给函数!f1函数的参数就是一个函数类型!
//所以在调用的时候就需要给它传入一个函数!这样才能和上面的函数声明对应上
//还学不会,就去看视频去吧,记住 , 凡是像 123 这样的值, 能出现的地方, 函数都可以出现
// * 应用场景2: 函数当成返回值, 闭包
function f2() {
let a = 1;
return function () {
return a++;
};
}
function f3() {
let a = 5;
return function () {
return a++;
};
}
// f2()返回值是一个函数
console.log(f2());
const f = f2();
console.log(f);
console.log(f());
console.log(f());
console.log(f());
console.log(f());
console.log(f());
console.log(f());
console.log(f3());
let d = f3();
console.log(d);
console.log(d());
console.log(d());
console.log(d());
console.log(d());
//* 以上的 回调 + 闭包, 都 是 函数当成"值"来用的经典应用场景
// * 以下是函数当成对象来用
// * 对象有属性和方法, 当然函数也有属性有方法
function func(a, b) {
return a + b;
}
// 查看函数名
console.log(func.name);
// 查看函数需要几个参数
console.log(func.length);
func.email = "498668472@qq.com";
console.log(func.email);
console.log(func(2, 3));
// ! 函数当成对象有啥用呢?
// * 用处太大了, 整个JS语言体系就靠它撑着了
// * 就算是你没学过编程, 至少听说过面向对象编程, 对象可以被继承,实现代码复用
// * 而JS就是基于原型,实现的继承, 而原型,就是在函数上创建一个普通对象而已
// console.log(func.prototype);
// * 后面要学到的类class,构造函数, 他们都是基于"函数是对象"这个前提的
示例截图:
自己写的代码如下:
// 数据类型
// 原始类型有以下
// number, string, boolean, undefined, null
// 数字 字符 true false 未定义 空
// 不可再分,是构成其他复合类型的基本单元
console.log(123, typeof 123)
console.log('php', typeof 'php')
// 字符串的时候需要加''引号
console.log(true, typeof true)
console.log(false, typeof false)
console.log(undefined, typeof undefined)
console.log(null, typeof null)
// Object 对象
//原始类型 又叫简单类型 单值类型, 比如声明一个变量a a的值=1
let a = 1
console.log(a)
console.log(a, typeof a)
console.log(typeof a)
// 瞎捣鼓的,老师的是最后这样写法
a = 'php'
console.log(typeof a)
a = ''
console.log(typeof a)
// 带了引号就是字符???
// 从上面可以看得出来,变量 a 的类型由 值 a的值来决定的
//引用类型
// 引用类型, 都是对象, 默认返回 object ,函数除外 function
// * array, object, function
// 引用类型: 类似其它语言中的"复用类型", 集合类型
// 引用类型的数据,由一个或多个, 相同, 或不同类型的"原始类型"的值构造
// 是一个典型的: 多值类型
// 这几句话是复制老师的
// // // // // // // // //
// 引用类型之数组类型
// // // // // // // // //
// 引用类型--数组类型
let sz = ['app', 123, 8888]
// 当前数组排序,我理解为0=app,1=123,2=8888
// 打印一下看看
console.log(sz)
// 打印一下其中的值
console.log(sz[1])
console.log(sz[2])
// 打印数组类型的正确方法
console.log(Array.isArray(sz))
// boolean 布尔类型
//引用类型--对象类型
// 对象类型类似数组类型
let duixiang = { name: '对象', shuzi: 123, shuzi2: 678 }
// 其中对象赋值的时候,要用英文的: ,不能用=
// 下面调佣一下看看
console.log(duixiang['name'])
// 声明的参数之后,这里需要用[''] 来调佣,注意注意
// 那如果全部调佣改如何调佣呢?看下面
console.log(duixiang)
// 全部调佣不需要再加[]
// 还有另外一种方式调用,例如全部调佣,
console.log(duixiang.name, duixiang.shuzi, duixiang.shuzi2)
// 直接使用变量.对象,来实现,不过这必须是合法对象,非合法对象不适用,例如下面的
let duixiang2 = { 'name mingzi': '名字', 'name _mz': '名字2', name3: '名字3' }
console.log(duixiang2['name _mz'])
// 上面是当对象是非法对象时,就必须以数组的方式来访问,必须用 变量[''] 这样
// * 对象最吸引人的,不是数组的语义化封装, 而是对数据操作的封装, 方法(语法与函数是一样的)
// 本质上来说, 对象, 就是变量与函数的封装, 内部, 变量->属性, 函数 -> 方法
// 先声明一个对象
let os = {
l: 'linux',
shuliang: 3,
jiage: 100,
zongji: function () {
// let sl =
// '当前' +
// os.l +
// '数量为' +
// os.shuliang +
// '单价为' +
// os.jiage +
// '总价为' +
// os.shuliang * os.jiage +
// '元'
// return sl
// 需要返回一下 return
// 上面是使用常规方式来实现的,下面是用this来实现
let sl =
'当前' +
this.l +
'数量为' +
this.shuliang +
'单价为' +
this.jiage +
'总价为' +
this.shuliang * os.jiage +
'元'
return sl
// 这里的this,相当于声明的那个变量 os的替换变量,当变量os改了之后,并不需要在对象里面的函数里面,挨个更改
},
}
console.log(os.zongji())
// console.log(os['zongji'])这是一个错误的写法,
// 自己试了试,其实可以这么理解,虽然声明的对象里面,如果出现了函数,就以函数的方式调佣,比如console.log(os.zongji())
// 打印上面的数据类型
console.log(typeof os)
// 上面提示的是对象
console.log(os instanceof Object)
// 上面提示的是布尔型
// 在实际工作中,数组和对象一般都是一起使用,使用演示如下
os = [
{ name: 'linux服务器', shuliang: 2, jiage: 100 },
{ name: 'win7服务器', shuliang: 2, jiage: 100 },
]
console.log(os[0])
console.log(os[1])
// let res = obj.map(item => item.num * item.price).reduce((acc, cur) => acc + cur);
// console.log(res);老师的js,也不知道怎么用
// ! 3. 函数
// 函数是一种数据类型 , 并且 还是 对象
console.log(typeof function () {})
// 函数即是函数, 也是对象
console.log(function () {} instanceof Object)
// 这句拿的老师的,
// ! (一) 函数是数据类型的好处?
// 可以当成普通值来使用, 例如充当函数的参数,或者函数的返回值
// 这个很重要, 当参数,就是回调函数, 当返回值,可以创建一个闭包
// js中很多高级应用, 都严重依赖这二个功能, 这也是"高阶函数"的基本特征
// * 应用场景1: 函数做为参数使用, 回调
function f1(hanshu) {
return console.log(hanshu())
}
///应用场景1,没看懂,得后面学习
// 调用f1, 匿名函数当成f1的参数
f1(function () {
return 'Hello 朱老师'
})
// 这里挑起了定义的function函数,
//函数是可以当成一个值的!
//既然可以看成一个值,那么就可以当作参数传递给函数!f1函数的参数就是一个函数类型!
//所以在调用的时候就需要给它传入一个函数!这样才能和上面的函数声明对应上
//还学不会,就去看视频去吧,记住 , 凡是像 123 这样的值, 能出现的地方, 函数都可以出现
// * 应用场景2: 函数当成返回值, 闭包
function f2() {
let a = 1
return function () {
return a++
}
}
function f3() {
let a = 5
return function () {
return a++
}
}
// f2()返回值是一个函数
console.log(f2())
const f = f2()
console.log(f)
console.log(f())
console.log(f())
console.log(f())
console.log(f())
console.log(f())
console.log(f())
console.log(f3())
let d = f3()
console.log(d)
console.log(d())
console.log(d())
console.log(d())
console.log(d())
//* 以上的 回调 + 闭包, 都 是 函数当成"值"来用的经典应用场景
// * 以下是函数当成对象来用
// * 对象有属性和方法, 当然函数也有属性有方法
function func(a, b) {
return a + b
}
// 查看函数名
console.log(func.name)
// 查看函数需要几个参数
console.log(func.length)
func.email = '498668472@qq.com'
console.log(func.email)
console.log(func(2, 3))
// ! 函数当成对象有啥用呢?
// * 用处太大了, 整个JS语言体系就靠它撑着了
// * 就算是你没学过编程, 至少听说过面向对象编程, 对象可以被继承,实现代码复用
// * 而JS就是基于原型,实现的继承, 而原型,就是在函数上创建一个普通对象而已
// console.log(func.prototype);
// * 后面要学到的类class,构造函数, 他们都是基于"函数是对象"这个前提的
老师的代码学习部分
// ! 细说函数
// ! 1. 命名函数
// 有名字的函数
// 命名: 动 + 名
// 声明
function getName(username) {
return "Hello " + username;
}
// 调用
console.log(getName("猪老师"));
// ! 2. 匿名函数
// 没有名字的函数
// function (username) {
// return "Hello " + username;
// }
// * 执行方式1: 立即执行
// * 立即执行函数( IIFE ): 声明 + 执行 2合1
// ! 2.1 IIFE
(function (username) {
console.log("Hello " + username);
})("灭绝老师");
console.log(
(function (username) {
return "Hello " + username;
})("灭绝老师")
);
// * IIFE: 阅后即焚, 不会给全局环境带来任何的污染,用来创建临时作用域
// node 模块, 就是用 IIFE 来写的
// * 执行方式2: 保存到一个变量中,
// ! 2.2 函数表达式
// 现在, "函数声明", 就变成了"变量声明", 只不过, 变量的值,是一个函数声明
const getUserName = function (username) {
return "Hello " + username;
};
// ! 表达式: 任何一个可以计算出确定 "值" 的过程
// * 100, 12+45, 'a'+'c',
console.log(getUserName("马老师"));
console.log(getUserName);
// ! 3. 箭头函数
// 匿名函数: 函数表达式, 将函数声明保存到一个变量中, 以后使用这个变量来引用这个函数
let f1 = function (a, b) {
return a + b;
};
console.log(f1(10, 20));
// 使用 箭头函数 来简化匿名函数的声明
// 匿名函数 --> 箭头函数的语法
// * 1. 去掉 function
// * 2. 在参数括号(...) 与 大括号{...} 之间使用 胖箭头 => 连接
f1 = (a, b) => {
return a + b;
};
console.log(f1(8, 9));
// 只有一个参数的时候, 括号可以不要了
f1 = username => {
return "Hello " + username;
};
// 如果只有一条语句,return ,可以不写大括号
// 因为只有一条语句,默认就是return ,所以 return 也可以不写的
f1 = x => {
return x * 2;
};
f1 = x => x * 2;
console.log(f1(40));
console.log(f1(90));
// 没有参数时, 括号一定要写上
f1 = () => "今天天气很好";
console.log(f1());
f1 = $ => 100 + 200;
console.log(f1());
f1 = _ => 100 + 200;
console.log(f1());
// 箭头函数, 内部的 this, 是固定的, 与它的上下文绑定 , 不能充当构造函数来创建对象
// 箭头函数内部没有 arguments 对象
// ! 使用场景
// 1. 如果函数需要多次调用, 用命名, 函数表达式, 都可以
// 2. 如果代码要求,必须遵循"先声明, 再调用"的规则, 那就必须用"函数表达式"
// 3. 如果只有完成一些特定的,一次性的工作, 不想留下任何痕迹, 用"IIFE", 模块
// 4. 如果调用函数时,需要一个函数充当参数,例如:回调, 就可以使用箭头函数来简化 匿名函数的 声明
// ! 数据类型
// ! 1. 原始类型
// * number, string, boolean, undefined, null
// 不可再分, 是构成其它复合类型的基本单元
console.log(123, typeof 123);
console.log("php", typeof "php");
console.log(true, typeof true);
console.log(undefined, typeof undefined);
console.log(null, typeof null);
// 原始类型, 简单类型, 基本类型: 一个变量,存一个值
// 单值类型
let a = 1;
console.log(typeof a);
a = "php";
console.log(typeof a);
// 动态语言: 变量的类型, 由它的值的类型决定
// ! 2. 引用类型
// 引用类型, 都是对象, 默认返回 object ,函数除外 function
// * array, object, function
// 引用类型: 类似其它语言中的"复用类型", 集合类型
// 引用类型的数据,由一个或多个, 相同, 或不同类型的"原始类型"的值构造
// 是一个典型的: 多值类型
// ! 2.1 数组
// 声明
const arr = ["手机", 2, 5000];
console.log(arr);
// 数组的索引是从0开始递增的正整数, 0, 1, 2
console.log(arr[0]);
console.log(arr[1]);
console.log(arr[2]);
console.log(arr[3]);
console.log(typeof arr);
// 判断数组类型的正确方法
console.log(Array.isArray(arr));
// 为了更直观的表达数据之间的关联, 可以将 数字索引 换 有意义 的"字符串"
// const arr1 = { 0: "手机", 1: 2, 2: 5000 };
// console.log(arr1);
// console.log(arr1[0]);
// console.log(arr1[1]);
// ! 2.2 对象
// 对象 更像一个语义化的 数组
// name, num , price : 属性,类似于变量
let obj = { name: "手机", num: 2, price: 5000 };
console.log(obj);
console.log(obj["name"]);
console.log(obj["num"]);
console.log(obj["price"]);
// 因为对象的属性名称都是合法的标识符,可以使用点来访问
console.log(obj.name, obj.num, obj.price);
// 当属性名是非常标识符时, 必须使用数组的方式来访问对象的属性
obj = { "my email": "admin@php.cn" };
console.log(obj["my email"]);
// * 对象最吸引人的,不是数组的语义化封装, 而是对数据操作的封装, 方法(语法与函数是一样的)
// 本质上来说, 对象, 就是变量与函数的封装, 内部, 变量->属性, 函数 -> 方法
obj = {
// name, num, price: 属性, 类似于变量
name: "手机",
num: 3,
price: 7000,
// total: 方法,实际上还是一个属性,只不过它的值是一个函数
total: function () {
// let str = obj.name + " 总计: " + obj.num * obj.price + " 元 ";
// 模板字面量, 来简化, 内部有变量的字符串
// let str = obj.name + " 总计: " + obj.num * obj.price + " 元 ";
// 反引号声明的模板字符串, 可以插入变量/表达式, 这叫"插值"
// 应该是对象内部, 使用 当前对象的一个引用, 这样才独立于外部对象
// let str = `${obj.name} 总计 ${obj.num * obj.price} 元`;
// this: 始终与当前对象绑定(执行环境 / 执行上下文 )
// this = obj
let str = `${this.name} 总计 ${this.num * this.price} 元`;
return str;
},
};
console.log(obj.total());
console.log(typeof obj);
console.log(obj instanceof Object);
// 实际工作中, 而是将数组与对象组合起来一起用
// obj是一个由三个对象构成的数组
obj = [
{ name: "手机", num: 2, price: 5000 },
{ name: "电脑", num: 2, price: 5000 },
{ name: "相机", num: 2, price: 5000 },
];
// 求三个商品的总和
let res = obj.map(item => item.num * item.price).reduce((acc, cur) => acc + cur);
console.log(res);
// ! 3. 函数
// 函数是一种数据类型 , 并且 还是 对象
console.log(typeof function () {});
// 函数即是函数, 也是对象
console.log(function () {} instanceof Object);
// ! (一) 函数是数据类型的好处?
// 可以当成普通值来使用, 例如充当函数的参数,或者函数的返回值
// 这个很重要, 当参数,就是回调函数, 当返回值,可以创建一个闭包
// js中很多高级应用, 都严重依赖这二个功能, 这也是"高阶函数"的基本特征
// 函数是js的一等公民, 就是通过这个体现的
// * 应用场景1: 函数做为参数使用, 回调
function f1(callback) {
// 参数 callback 是一个函数
console.log(callback());
}
// 调用f1, 匿名函数当成f1的参数
f1(function () {
return "Hello 朱老师";
});
// * 应用场景2: 函数当成返回值, 闭包
function f2() {
let a = 1;
return function () {
return a++;
};
}
// f2()返回值是一个函数
console.log(f2());
const f = f2();
console.log(f);
console.log(f());
console.log(f());
console.log(f());
console.log(f());
console.log(f());
console.log(f());
//* 以上的 回调 + 闭包, 都 是 函数当成"值"来用的经典应用场景
// * 以下是函数当成对象来用
// * 对象有属性和方法, 当然函数也有属性有方法
function func(a, b) {
return a + b;
}
// 查看函数名
console.log(func.name);
// 查看函数需要几个参数
console.log(func.length);
func.email = "498668472@qq.com";
console.log(func.email);
console.log(func(1, 2));
console.log(func);
// ! 函数当成对象有啥用呢?
// * 用处太大了, 整个JS语言体系就靠它撑着了
// * 就算是你没学过编程, 至少听说过面向对象编程, 对象可以被继承,实现代码复用
// * 而JS就是基于原型,实现的继承, 而原型,就是在函数上创建一个普通对象而已
// console.log(func.prototype);
// * 后面要学到的类class,构造函数, 他们都是基于"函数是对象"这个前提的