028 (H5*) 商城实战
目录:
正文:
1:创建项目
ESlintESLint 是一个ECMAScript/JavaScript 语法规则和代码风格的检查工具,它的目标是保证代码的一致性和避免错误。
utit tests是单元测试
E2E(End To End)即端对端测试,属于黑盒测试,通过编写测试用例,自动化模拟用户操作,确保组件间通信正常,程序流数据传递如预期。
2:安装包
1: vue-router
cnpm i vue-router -S
2: i-view
install view-design --save
3: axios 网络请求 异步请求
cnpm install axios
4:vuex 组件传值
cnpm install vuex --save
5:安装mint-UI 是移动端的app
cnpm i mint-ui -S
目录:
1:call和apply方法调用
2:bind方法复制
3:函数中的几个属性值
4:高阶函数,函数作为参数
5:高阶函数,函数作为返回值。
6: 作用域链,作用域,预解析
7:闭包--延长作用域链
8: 沙箱:测试,虚拟环境
1:call和apply方法调用
<script>
function f1 (x, y) {
console.log("结果是:"+(x+ y) + this);
}
// 函数的调用
f1(10, 20);
console.log("===========");
//1: 此时的f1实际上是当成对象来使用的,对象可以调用方法,apply和call方法也是函数的调用的方式
f1.apply();
f1.call();
//2: apply和call都可以让函数或者方法来调用,传入参数和函数自己调用的写法不一样,但是效果是一样的, apply传入的是数组, call,传入的是参数
f1.apply(null, [100, 200]);
f1.call(null, 100, 200);
console.log("===========");
function f2(x, y){
console.log("这个函数是window对象的一个方法"+ (x+y) + this);
console.dir(this);
}
window.f2(10, 20);
var obj = {
age: 10,
name: "张三",
}
//3: apply和call可以改变this的指向,
window.f2.call(obj, 10, 20);
window.f2.apply(obj, [10,20]);
// 4:apply和call方法实际上并不在函数这个实例对象中,而是在Function的prototype,原型对象中。
原型对象可以看成+方法,实例方法可以当成-方法。调用+方法时候可以当成对象。
console.log(f2.__proto__ == Function.prototype);
console.log(Function.prototype); //{ [native code] }
console.dir(Function);
</script>
2:bind方法复制
<script>
console.log("===== 11 =====")
function f1 (x, y ){
console.log((x+y) + " :======>>>>"+this );
console.dir(this);
}
f1.bind();
// 方法复制了一份,并且传递参数,结果还是方法,方法没有调用。此时f1是对象。
// bind方法是复制的意思,可以在复制的时候传递参数,也可以在复制之后传递参数
// apply 和 call 是调用的时候改变this的指向
// bind是 复制的时候修改this的指向
var ff = f1.bind(null, 10, 20);
console.log (ff);
ff();
var f2 = f1.bind(null);
f2(10, 20);
console.log("===== 22 =====")
// bind是方法复制,apply和call是方法调用
function Person (){
this.age = 10;
}
Person.prototype.eat = function () {
console.log("这个是吃");
};
var per = new Person;
var ff = f1.bind(per);
ff(10, 20);
console.log("===== 33 =====")
function Person(age) {
this.age = age;
}
Person.prototype.play = function () {
console.log(this + "========>>>>" + this.age);
}
function Student (age) {
this.age = age;
}
var per = new Person(10);
var stu = new Student(20);
var paly2 = per.play.bind(stu);
paly2();
</script>
3: 函数中几个属性
<script>
//函数中有一个name属性----->函数的名字,name属性是只读的,不能修改
//函数中有一个arguments属性--->实参的个数
//函数中有一个length属性---->函数定义的时候形参的个数
//函数中有一个caller属性---->调用(f1函数在f2函数中调用的,所以,此时调用者就是f2)
function f1(x,y) {
console.log(f1.name);
console.log(f1.arguments.length);
console.log(f1.length);
console.log(f1.caller);//调用者
}
f1.name="f5";
f1(10,20,30,40);
console.dir(f1);
function f2() {
console.log("f2函数的代码");
f1(1,2);
}
f2();
</script>
4:高阶函数之参数是函数
<script>
//fn是参数,最后作为函数使用了,函数是可以作为参数使用
function f1(fn) {
console.log("f1的函数");
fn();//此时fn当成是一个函数来使用的
}
//1: 传入匿名函数
f1(function () {
console.log("我是匿名函数");
});
console.log("======= 22 ========");
// 命名函数
function f2() {
console.log("f2的函数");
}
// 2:传入的是命名函数
f1(f2);
//函数作为参数的时候,如果是命名函数,那么只传入命名函数的名字,没有括号
</script>
5: 函数作为返回值
<script>
console.log("======== 11 =========");
function f1() {
console.log("f1函数的开始");
return function () {
console.log("我是函数,但是我是我是我为函数的返回值");
};
// 我是不会执行的,因为此行代码上面有return
console.log("f1函数的结束");
}
var f2 = f1();
f2();
console.log("======== 22 =========");
var num=10;
console.log(typeof num);//获取num这个变量的数据类型
var obj={};//对象
//判断这个对象是不是某个类型的
console.log(obj instanceof Object);
//获取某个对象的数据类型的样子
//Object.prototype.toString.call(对象);//此时得到的就是这个对象的类型的样子
//此时输出的是Object的数据类型 [object Object]
console.log(Object.prototype.toString());
//输出的数组的数据类型 [object Array]
console.log(Object.prototype.toString.call([]));
var arr=[10,20,30];
console.log(Object.prototype.toString.call(arr));
console.log("======== 33 =========");
//获取某个对象的类型是不是你传入的类型
//[10,20,30] 是不是"[object Array]"
//type---是变量----是参数----"[object Array]"
//obj---是变量-----是参数----[10,20,30];
//判断这个对象和传入的类型是不是同一个类型
function getFunc(type) {
return function (obj) {
return Object.prototype.toString.call(obj) === type;
}
}
var ff = getFunc("[object Array]");
var result = ff([10, 20, 30]);
console.log(result);
var ff1 = getFunc("[object Object]");
var dt = new Date();
var result1 = ff1(dt);
console.log(result1);
</script>
6:作用域,作用域链,预解析
1:局部变量。函数中的变量是局部变量,外边无法访问。
2:预解析:变量的声明,和函数的声明提前
<script>
// 变量---->局部变量和全局变量,
// 作用域:就是变量的使用范围
// 局部作用域和全局作用域
// js中没有块级作用域---一对括号中定义的变量,这个变量可以在大括号外面使用
// 函数中定义的变量是局部变量
while(true){
var num=10;
break;
}
console.log(num);
{
var num2=100;
}
console.log(num2);
if(true){
var num3=1000;
}
console.log(num3);
function f1() {
//局部变量
var num1=10;
}
// console.log(num1);
console.log("======== 22 ======");
// 作用域链:变量的使用,从里向外,层层的搜索,搜索到了就可以直接使用了
// 层层搜索,搜索到0级作用域的时候,如果还是没有找到这个变量,结果就是报错
var num=10; //作用域链 级别:0
var num2=20;
var str = "abc"
function f1() {
var num2=20;
function f2() {
var num3=30;
console.log(num);
}
f2();
}
f1();
//预解析:就是在浏览器解析代码之前,把变量的声明和函数的声明提前(提升)到该作用域的最上面
//变量的提升
console.log(num);
var num=100;
//函数的声明被提前了
f1();
function f1() {
console.log("这个函数,执行了");
}
var f2;
f2=function () {
console.log("小杨好帅哦");
};
f2();
</script>
7:闭包
1:闭包的定义:
函数A中,有一个函数B,函数B中可以访问函数A中定义的变量或者数据,此时就行程了闭包。
闭包缓存数据
总结:如果想要缓存数据,需要把数据放在外层函数和内层函数之间。
闭包的作用:缓存数据。优点也是缺点,没有及时释放
局部变量在函数中,函数使用结束后,局部变量就会被自动释放。
闭包后,里面的局部变量的使用作用域链就会被延长。
<script>
/* 闭包
* 闭包的概念:函数A中,有一个函数B,函数B中可以访问函数A中定义的变量或者数据,此时就行程了闭包。
*闭包的模式:函数闭包和对象闭包
* 闭包的作用:缓存数据,延长作用域链
* 闭包的优点和缺点:缓存数据
* 闭包的应用:
* ****/
console.log("======= 11 ========");
// 1:函数式闭包
function f1() {
var num = 10;
// 函数
function f2() {
console.log(num);
}
f2();
}
f1();
console.log("======= 22 ========");
// 2:对象是闭包
function f3() {
var num1 = 20;
// 对象
var obj = {
age : num1,
}
console.log(obj.age);
}
f3();
console.log("======= 33 ========");
function f4() {
var num4 = 40;
return function () {
console.log(num4);
return num4;
};
}
var ff1 = f4();
var result = ff1();
console.log(result);
console.log("======= 44 ========");
function f5() {
var num5 = 50;
var obj = {
age : num5,
}
return obj;
}
var resultObj = f5();
var result5 = resultObj.age;
console.log(result5);
</script>
2:闭包的例子
<script>
console.log("======= 11 =========");
function f1 () {
var num = 10;
num ++ ;
console.log(num);
}
f1(); // 11
f1(); // 11
f1(); // 11
console.log("======= 22 =========");
// 闭包缓存数据
// 总结:如果想要缓存数据,需要把数据放在外层函数和内层函数之间。
// 闭包的作用:缓存数据。优点也是缺点,没有及时释放
// 局部变量在函数中,函数使用结束后,局部变量就会被自动释放。
// 闭包后,里面的局部变量的使用作用域链就会被延长。
function f2() {
var num = 20;
return function () {
num ++;
return num;
};
}
var ff1 = f2();
console.log(ff1()); // 21
console.log(ff1()); // 22
console.log(ff1()); // 23
console.log("======= 33 =========");
// 产生3次相同的随机数
//
function f3() {
var num3 = parseInt(Math.random()*10+1);
return function () {
console.log(num3);
}
}
var ff3 = f3();
ff3();
ff3();
ff3();
</script>
8:沙箱:虚拟测试和真实世界结果一样,不影响真实世界。
1:沙箱的定义和2中格式
<script>
//沙箱:环境,黑盒,在一个虚拟的环境中模拟真实世界,做实验,实验结果和真实世界的结果是一样,但是不会影响真实世界
// 沙箱 函数的自调用
console.log("======== 11 ========");
// 沙箱的模板,函数自调用两种格式
// 格式一: ()();
(function () {
var num = 10;
console.log(num + 10);
})();
// 格式二:使用的比较多. (());
(function () {
var num = 10;
console.log(num + 20);
}());
</script>
9:递归
1:定义:自己调用自己一定 要有结束条件。
<script>
console.log("======= 11 =======");
// 求n个数的和
// 倒序递归,结束条件 5+4+3+2+1
function getSum(n) {
// 结束条件
if(n ==1){
return 1;
}
return n + getSum(n - 1);
}
console.log(getSum (5));
/*
*
* 执行过程:
* 代码执行getSum(5)--->进入函数,此时的x是5,执行的是5+getSum(4),此时代码等待
* 此时5+getSum(4),代码先不进行计算,先执行getSum(4),进入函数,执行的是4+getSum(3),等待, 先执行的是getSum(3),进入函数,执行3+getSum(2),等待,先执行getSum(2),进入函数,执行 2+getSum(1);等待, 先执行getSum(1),执行的是x==1的判断,return 1,所以,
* 此时getSum(1)的结果是1,开始向外走出去
* 2+getSum(1) 此时的结果是:2+1
* 执行:
* getSum(2)---->2+1
* 3+getSum(2) 此时的结果是3+2+1
* 4+getSum(3) 此时的结果是4+3+2+1
* 5+getSum(4) 此时的结果是5+4+3+2+1
*
* 结果:15
*
* */
</script>
注意: