怎么申请做网站,可以做公众号的网站吗,软件开发公司优势,阿里云可以建设网站吗一、函数定义和调用
1.函数的定义方式
方式一 函数声明方式 function 关键字(命名函数) function fn(){}方式二 函数表达式#xff08;匿名函数#xff09; var fn function(){}方式三 new Function() var f new Function(a,b,console.log(a b););//语法
var fn new Fu…一、函数定义和调用
1.函数的定义方式
方式一 函数声明方式 function 关键字(命名函数) function fn(){}方式二 函数表达式匿名函数 var fn function(){}方式三 new Function() var f new Function(a,b,console.log(a b););//语法
var fn new Function(参数1,参数2,....,函数体); 注意 Function里面参数都必须是字符串格式 第三种方式执行效率很低也不方便书写因此较少使用 所有函数都是Function的实例对象 函数也属于对象 2.函数的调用
!DOCTYPE html
html langen
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0title01函数的定义和调用方式/title
/head
bodyscript//1.自定义函数命名函数function fn(){}//2.函数表达式匿名函数var fun function(){}//3. 利用new Function((参数1,参数2,....,函数体);var f new Function(a,b,console.log(a b););f(1,2);//4. 所以的函数都是Function的实例对象console.dir(f);//5.函数也属于对象console.log(f instanceof Object);/script
/body
/html函数的调用 !DOCTYPE html
html langen
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0title02函数的调用/title
/head
bodyscript//1.普通函数function fn(){console.log(人生的巅峰);}fn();fn.call();//2.对象的方法var o {sayHi : function(){console.log(人生的巅峰2);}}o.sayHi(); //对象.函数();//3.构造函数function Star(){}new Star();//4.绑定事件的函数//btn.onclick function(){} //点击了按钮就可以调用这个函数//5.定时器函数setInterval(function(){},1000);//6.立即执行函数(function(){console.log(hello);})();/script
/body
/html二、this
1.函数内部的this指向
这些this的指向是当我们调用函数的时候确定的调用方式不同决定了this的指向不同。
调用方式this指向普通函数调用window构造函数调用实例对象原型对象里面的方法也指向了实例对象对象方法调用该方法所属的对象事件绑定方法绑定事件的对象定时器函数window立即执行函数window
!DOCTYPE html
html langen
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0title03this的指向/title
/head
bodybutton点击/buttonscript//函数的不同调用方式决定了this的指向不同 //1.普通函数this指向window对象function fn(){console.log(普通函数的this--- this);}window.fn();//2.对象的方法,this指向的是对象ovar o {sayHi : function(){console.log(对象方法的this--- this);}}o.sayHi(); //对象.函数();//3.构造函数function Star(){}Star.prototype.sing function(){console.log(构造的this--- this);}var ldh new Star();ldh.sing();//4.绑定事件函数this指向的函数调用者 比如btn.onclick 函数中的this指向的btn对象var btn document.querySelector(button);btn.onclick function(){console.log(绑定事件的函数中的this--- this);}//5.定时器函数this,指向的就是windowwindow.setTimeout(function(){console.log(定时器函数中的this--- this);},1000);//6.立即执行函数 this还是指向window(function(){console.log(立即执行函数this--- this);})();/script
/body
/html2.改变函数内部this指向
2.1 call方法 call() 方法调用一个对象简单的理解调用函数的方式但是它可以改变函数this指向 应用场景经常做继承 !DOCTYPE html
html langen
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0title04改变函数内this指向call方法/title
/head
bodyscript//js 中一共是提供了三种方法可以改变this的指向:call() apply() bind()var obj {name: amdin}function fn(a,b){console.log(this);console.log(a b);}//1.call() 改变函数this的指向fn.call(obj,1,2);function Father(name,age,sex){this.name name;this.age age;this.sex sex;}function Son(name,age ,sex){//this:指向SonFather.call(this,name,age,sex);}var son new Son(刘德华,80,男);/script
/body
/html2.2 apply方法 apply() 方法调用一个函数。简单的理解为调用函数的方式但是它可以改变函数的this指向 应用场景经常跟数组有关系 !DOCTYPE html
html langen
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0title05.改变函数内this指向apply方法/title
/head
bodyscript//js 中一共是提供了三种方法可以改变this的指向:call() apply() bind()//2.apply() 方法 应用/运用var obj {name: admin}function fn(arr){console.log(this);console.log(arr);}fn.apply(obj,[pink,red]);fn([pink,red])//1.也是调用函数第二个可以改变函数内部的this指向//2.但是它的参数必须是数组伪数组//3.apply的主要应用比如我们可以利用apply借助于数学内置对象求数组最大值//Max.max();var arr [1,66,3,99,4];var arr1 [red,pink]// var max Math.max.apply(null,arr);// var min Math.min.apply(null,arr);var max Math.max.apply(Math,arr);var min Math.min.apply(Math,arr);console.log(max);console.log(min);/script
/body
/html2.3 bind 方法 bind()方法不会调用函数但是能改变函数内部this指向返回的是原函数改变this之后产生的新函数。 如果指向改变this指向并且不想要调用这个函数的时候就可以用bind **应用场景**不调用用户但是还想改变this指向 !DOCTYPE html
html langen
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0title06.05.改变函数内this指向bind方法/title
/head
bodybutton点击/buttonbutton点击/buttonbutton点击/buttonscript//js 中一共是提供了三种方法可以改变this的指向:call() apply() bind()//2. bind() 意思就是捆绑或绑定var obj {name:admin}function fn(a,b){console.log(this);console.log(a b);}//fn(1,2);var f fn.bind(obj,1,2);f();//1)不会调用原来的函数可以改变原来函数内部的this指向//2)返回的是原函数改变this之后产生的新函数//3)如果有函数我们不需要立即调用但是又想改变这个函数内部的this指向此时我们可以bind//4)我们有一个按钮当我们点击之后就想用禁用这个按钮3秒之后开启这个按钮// var btn1 document.querySelector(button);// btn1.onclick function(){// this.disabled true;// //设置定时任务// setTimeout(function(){// this.disabled false; //定时器函数中this指向的是window对象// }.bind(this),3000); //因为这里的this是写在定时器之外所以这里的this还是btn这个对象// }var btns document.querySelectorAll(button);//给每个按钮注册点击事件for(var i 0; i btns.length; i){btns[i].onclick function(){this.disabled true;//3秒后按钮重新可以被点击setTimeout(function(){this.disabled false;}.bind(this),3000);}}/script
/body
/html2.4 call、apply、bind三者异同
共同点 都可以改变this的指向 不同点 call和apply会调用函数并且改变函数内部的this指向call和apply传参不一样call传递参会使用逗号分隔apply使用数组传参bind必会调用函数可以改变函数内部的this指向 应用场景 call经常做继承apply经常跟数组有关系比如借助数学对象实现数组最大值和最小值bind不调用函数但是还想改变this的指向比如改变定时器内部的this指向
三、严格模式 官网资料地址https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Strict_mode 1.什么是严格模式
Js除了提供正常的模式之外还提供了严格模式strict mode。
ES5的严格模式采用具有限制性js变体的一种方式——即在严格的条件下运行js代码。
严格模式在IE10以上版本浏览器中才会被执行旧版本浏览器中会被忽略。 严格模式对正常的js语义做了一些修改 清除了js语法的一些不合理、不严谨之处、减少了一些怪异行为清除了js代码运行的一些不安全之处保证代码的运行安全。提高了编译器的效率增加运行速度禁用了ECMAScript的未来本版中可能会定义的一些语法为未来新版本的JS 做了铺垫。比如一些保留关键字class、enum、export、extends、import、super不能做为变量
2.开启严格模式
严格模式可以应用到整个脚本或者是个别函数中因此在使用的时候我们可以将yan模式分为脚本开启严格模式还是函数开启严格模式两种情况。
!DOCTYPE html
html langen
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0title07.开启严格模式/title
/head
body!-- 为整个脚本script标签开启严格模式 --scriptuse strict;// 下面js代码就会按照严格模式执行代码/scriptscript// 给某个函数开启严格模式function fn(){use strict;// 下面js代码就会按照严格模式执行代码}function fn(){use strict;// 下面js代码就会按照严格模式执行代码}/scriptscript(function(){use strict;// 下面js代码就会按照严格模式执行代码})();/script
/body
/html2.1 脚本开启严格模式 有的script脚本是严格模式有的script是正常模式这样不利于文件的合并所以可以将整个脚本文件放在一个立即执行函的匿名函数里面这样独立创建有一个作用域而不影响其它的script脚本文件。 !DOCTYPE html
html langen
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0title08.开启严格模式后的变化/title
/head
bodyscriptuse strict; //use strict严格的//1.我们的变量名必须先声明后使用//num 10; //在严格模式下变量必须用var声明后才能使用// console.log(num);var num 10;console.log(num);//2.我们不能随意删除已经声明好变量//delete num; //删除变量num//console.log(num);//3.严格模式下全局作用域中函数的this 是undefinedfunction fn(){console.log(this); //undefined}fn();//4.在严格模式下如果构造函数不加new调用this指向的是undefined如果给它赋值则会报错function Star(){this.sex 男}//Star();var ldh new Star();console.log(ldh.sex);//5.定时器this指向还是windowsetTimeout(function(){console.log(this);},2000);//6.在严格模式下函数里面的参数不允许重名var a 1;a 2;// function fn(a,a){ //参数名不允许重复// console.log(a);// }// fn();/script
/body
/html2.2 为函数开启严格模式 要给某个函数开启严格模式需要use strict;写到函数体所有语句之前 function fn(){use strict;//....
}//表示当前fn函数开启了严格模式四、高阶函数 高阶函数是对其它函数进行操作的函数它接受函数作为参数或者将函数作为返回值输出。 !DOCTYPE html
html langen
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0title09高阶函数/titlestylediv{position: absolute;width: 100px;height: 100px;background-color: pink;}/stylescript srcanimate.js/script
/head
bodydiv/divscript//高阶函数——函数可以作为参数传递function fn(a,b,callback){console.log(a b);callback callback();}fn(1,2,function(){console.log(我是最后调用的);})/script
/body
/html五、闭包
1.变量的作用域【复习】
变量根据作用域的不同分为全局变量和局部变量
函数内部可以使用全局变量函数外部不可以使用局部变量当函数执行完毕后本作用域内局部变量会被销毁
2.什么是闭包 closure闭包。指有权访问另一个函数作用域中变量的函数。 简单的理解一个作用域可以访问另一个函数内部的局部变量 !DOCTYPE html
html langen
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0titleDocument/title
/head
bodyscript//闭包指有权访问另一个函数作用域中的变量的函数//闭包我们fun这个函数的作用域访问了另一个函数fn里面的局部变量numfunction fn(){var num 10;function fun(){console.log(num);}fun();}fn();/script
/body
/html3.闭包的作用 作用延申变量的作用范围 !DOCTYPE html
html langen
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0title11.闭包的作用/title
/head
bodyscript//闭包指有权访问另一个函数作用域中的变量的函数//一个作用域可以访问另一个函数的局部变量//fn外面的作用域可以访问fn内部的局部变量//闭包的主要作用延申了变量的作用范围function fn(){var num 10;return function(){console.log(num);};}var f fn();f();/script
/body
/html4.闭包案例
4.1 得到li当前的所以那红
!DOCTYPE html
html langen
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0title12.闭包应用-点击li输出索引号/title
/head
bodyul classnavli星期一/lili星期二/lili星期三/lili星期四/li/ulscript//闭包//1.我们可以利用动态添加属性的方式给每个li添加索引var lis document.querySelector(.nav).querySelectorAll(li);// for(var i 0; i lis.length; i) {// lis[i].index i;// lis[i].onclick function(){// console.log(i); //表示i是循环中的i// //console.log(this.index);// }// }//2.利用闭包的方式得到每个当前小li的索引号for(var i 0; i lis.length; i){//利用for循环创建了4个立即执行函数//立即执行哈桑农户也为小闭包//立即执行函数为小闭包因为立即执行函数里卖弄的任何一个函数都可以使用它的i这个变量(function(i){lis[i].onclick function(){console.log(i);}})(i);}/script
/body
/html4.2 闭包定时器中的应用
!DOCTYPE html
html langen
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0title13.闭包应用-定时器/title
/head
bodyul classnavli星期一/lili星期二/lili星期三/lili星期四/li/ulscript// 闭包应用- 3秒钟之后打印所有li元素的内容var lis document.querySelector(.nav).querySelectorAll(li);for(var i 0; i lis.length; i){//生成了4个立即执行函数(function(i){setTimeout(function(){console.log(lis[i].innerHTML);},3000);})(i);}/script
/body
/html4.3 打车价格案例 需求计算打车价格 //1.打车的起步价13(3公里以内),之后每多一公里增加5块钱用户输入公里数就可以计算打车的价格 //2.如果有拥堵的情况总价格多收取10块钱拥堵费 !DOCTYPE html
html langen
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0title14.计算打车的价格/title
/head
bodyscript//需求计算打车价格//1.打车的起步价13(3公里以内),之后每多一公里增加5块钱用户输入公里数就可以计算打车的价格//2.如果有拥堵的情况总价格多收取10块钱拥堵费var car (function(){var start 13; //起步价局部变量var total 0; //总价局部变量// 返回对象return {//正常的价格price: function(n){ //n是用户打车的距离if(n 3){total start;//小于或等于3公里就是起步价} else {total start (n - 3) * 5;}return total;},//拥堵之后的费用yd:function(flag){ //flag是是否拥堵return flag? total 10:total;}}})();var total1 car.price(5);console.log(total1); //23var total2 car.yd(true);console.log(total2); // 33var total3 car.price(1); //13var total4 car.yd(false); //13console.log(total3, total4);/script
/body
/html六、递归
1.什么是递归
递归如果一个函数再内部可以调用其本身那么这个函数他就是递归函数。
简单理解函数内部自己调用了自己这个函数就是递归函数 **注意**递归函数的作用和循环效果一样由于递归很容易出现栈移除所以要加退出的条件 2.求1~n的阶乘 3! 1 × 2 × 3 5 1 × 2 × 3 × 4 × 5 n! 1 × 2 × … n !DOCTYPE html
html langen
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0title15.求n的阶乘/title
/head
bodyscript//利用递归函数求n的阶乘function fn(n){if(n 1){ //结束条件return 1;}return n * fn(n - 1);}//n1 fn(1) 1;//n2 fn(2) 2 * f(1) 2 * 1;//n3 fn(3) 3 * fn(3-1) 3 * 2 * 1;//n4 fn(4) 4 * fn(4-1) 4 * 3 * 2 * 1;//....console.log(fn(4));console.log(fn(10));/script
/body
/html3.斐波拉契数列
!DOCTYPE html
html langen
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0title16.斐波拉契数列/title
/head
bodyscript//斐波拉契数列 1 1 2 3 5 8 13 21 34 55....function fb(n){if(n 1 || n 2){ //结束条件return 1;}//数的值是前两个数的和return fb(n - 1) fb(n -2);}//fb(1) 1//fb(2) 1//fb(3) fb(3-1) fb(3-2) fb(2) fb(1) 1 1 2//fb(4) fb(4-1) fb(4-2) fb(3) fb(2) 2 1 3//fb(5) fb(5-1) fb(5-2) fb(4) fb(3) 3 2 5//fb(6) fb(6-1) fb(6-2) fb(5) fb(4) 5 3 8//...console.log(fb(10));/script
/body
/html4.利用递归遍历数据
!DOCTYPE html
html langen
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0title17.利用递归遍历数据/title
/head
bodyscriptvar data [{id:1,name:家电,goods:[{id:11,gname:冰箱,goods:[{id:111,name:海尔},{id:222,name:美的}]},{id:22,name:洗衣机,goods:[{id:111,name:小天鹅},{id:222,name:美的}]}]}];//1.利用foreach遍历里面的每一个对象function getID(json,id){var obj {}json.forEach(function(item){//console.log(item); //2个数组元素if(item.id id){ //如果对象的id 传入的id//console.log(item);obj item; //将一级分类对象给到自定义对象obj} else if(item.goods item.goods.length 0){ //我们想要得到数据11 和 12 可以利用递归函数//里面应该有goods这个数组并且数组长度部位0obj getID(item.goods,id)} });return obj;}console.log(getID(data,1));console.log(getID(data,11));console.log(getID(data,111));/script
/body
/html七、浅拷贝和深拷贝
1.浅拷贝 浅拷贝只是拷贝一层更深层次对象级别的只拷贝引用 !DOCTYPE html
html langen
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0title18.浅拷贝/title
/head
bodyscript//浅拷贝只是拷贝一层更深层次对象级别的只拷贝引用var obj {id:1,name:admin,msg:{age:18}}var o {};for(var k in obj){//k 是属性名 obj[k] 该属性的值o[k] obj[k]; //设置对象o属性k的值为obj[k]}// o.msg.age 20;// console.log(o);// console.log(obj);console.log(---------------------------);//Object.assign(o,obj);o.msg.age 21;console.log(o);console.log(obj);console.log(o obj);/script
/body
/html2.深拷贝 深拷贝拷贝多层每一级的数据都会拷贝 !DOCTYPE html
html langen
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0title19.深拷贝/title
/head
bodyscript//深拷贝拷贝多层每一级的数据都会拷贝var obj {id:1,name:admin,msg:{age:18}}var o {};//封装函数function deepCopy(newObj,oldObj){for(var k in oldObj){//1.判断我们的属性值属于哪种数据类型//获取属性值var item oldObj[k]if(item instanceof Array){ //如果是数组newObj[k] [];deepCopy(newObj[k],item);} else if(item instanceof Object){ //如果是对象newObj[k] {};deepCopy(newObj[k],item);} else {//属于简单类型newObj[k] item;}}}deepCopy(o,obj);o.msg.age 20;console.log(o);console.log(obj);/script
/body
/html