1.两种数学方法
1.Math.random()*n
2.Math.random()
2.参数的作用
作用:为了使函数抽象,函数内部的内容独立,可以通过加入参数让函数执行不同的特征 多态!
a,b,c就是形参
1,2,3就是实参
实参按照顺序赋值给形参
如果对应的形参没有实参值,这个形参的值是undefined
3.纯函数
当函数中不使用外部的全局变量,或者不改变外部的全局变量时,这个函数就叫做纯函数
例:function randomColor(){
var str="#"
for(var i=0
str+=(~~(Math.random()*16)).toString(16)
}
return str
}
var color=randomColor()
console.log(color)
4.参数分为三种类型
1、必填参数
2、初始值参数(ES6)
3、可选参数
ES5中真的参数是没有固定的
参数也可以有顺序
例:b=1是默认值参数
当给入b值时,b的值就是对应的值,如果没有给值时,b的值是默认值1
function fn(a,b=1,c){
console.log(a,b,c); //a必填参数 b默认参数 c可选参数因为没给
}
fn(5);
fn(5,2);//a=5 b=1 c=undefind
5.参数的数量问题(arguments)
参数有时候是无限的 ES5
1.使用arguments来完成参数调用
2.ES6 ...arg来完成参数调用
1.ES5 arguments.length是参数长度,这个是实参长度,也就是实参数量
例:function getMinAndMax(){
var obj={min:arguments[0],max:arguments[0]}
for(var i=1
obj.min > arguments[i] ? obj.min=arguments[i] : 1
obj.max <arguments[i] ? obj.max=arguments[i] : 1
}
console.log(obj)
}
2.ES6 ...arg 这种方式使用多个参数
例:function getMinAndMax(...arg){
var obj={min:arg[0],max:arg[0]}
for(var i=1
obj.min > arg[i] ? obj.min=arg[i] : 1
obj.max <arg[i] ? obj.max=arg[i] : 1
}
console.log(obj)
}
5.1上述两种方式的区别
1. 全部参数 ES5
function fn(a){
console.log(arguments);
}
fn(1,2,3);
2. ...arg 剩余参数 ES6
function fn1(a,...arg){
console.log(a,arg)
}
fn1(1,2,3)
区别:第一种全部赋值给arg 第二种方法 1传给a 2.3赋值给arg
ES5 和 ES6的写法可以混合
6.引用地址问题
参数引用地址改变 造成结果的改变
例: var obj={a:1,b:2}
function fn(obj){
obj.a=10;
}
fn(obj);
console.log(obj);
例: var obj1={a:1,b:2}
function fn1(obj1){
obj1={a:10,b:1};
}
fn1(obj1);
console.log(obj1);
7.iterator 迭代器
function fn(){
console.log(arguments.callee);
console.log(arguments.callee.caller);
}
function fn1(){
fn();
}
fn1();
fn();
8.随机透明度案例
希望可以随机透明度 如果透明度设置为1 则不透明,如果透明度设置为小于0,则透明度为0
如果不设置则随机透明,或者设置1以下0以上,
希望设置固定色彩时,该色彩固定,不设置该色彩时,这个颜色随机
例:function randomColor(alpha,r,g,b){
var str="rgba("
or(var i=0
if(arguments[i]===undefined){
i===0 ? alpha=(Math.random()).toFixed(2) : str+=~~(Math.random()*256)
}else if(arguments[i]<0){
i===0 ? alpha=0 : str+="0"
}else if(i===0 ? arguments[i]>1 : arguments[i]>255){
i===0 ? alpha=1 : str+="255"
}
if(i>0) str+=","
}
str+=alpha+")"
return str
if(alpha===undefined) alpha=(Math.random()).toFixed(2)
if(alpha<0) alpha=0
if(alpha>1) alpha=1
if(r===undefined) r=~~(Math.random()*256)
if(r>255) r=255
if(r<0) r=0
if(g===undefined) g=~~(Math.random()*256)
if(g>255) g=255
if(g<0) g=0
if(b===undefined) b=~~(Math.random()*256)
if(b>255) b=255
if(b<0) b=0
return `rgba(${r},${g},${b},${alpha})`
}
var color= randomColor(2,256)
console.log(color)
代码简化:function randomColor(alpha,r,g,b){
if(alpha===undefined) alpha=(Math.random()).toFixed(2)
if(alpha<0) alpha=0
if(alpha>1) alpha=1
if(r===undefined) r=~~(Math.random()*256)
if(r>255) r=255
if(r<0) r=0
if(g===undefined) g=~~(Math.random()*256)
if(g>255) g=255
if(g<0) g=0
if(b===undefined) b=~~(Math.random()*256)
if(b>255) b=255
if(b<0) b=0
return `rgba(${r},${g},${b},${alpha})`
9.return用法
1、返回值
2、跳出函数,不执行return后面的语句
1.1任何函数执行后都会有返回值,如果使用return返回结果时,函数则返回这个内容如果没有使用return ,或者return后面没有别的内容时,返回undefined
function fn(){
return 1;
}
var a=fn();
console.log(a)
1.2返回值只能返回一个.如果要返回多个时,我们可以通过返回对象或者返回数组来返回多个值
function fn(){
return {a:1,b:2};
}
function fn(){
return [1,2];
}
2.1跳出
function fn(){
console.log("a");
return;
console.log("b");
}
9.1工厂模式
function getObj(name,age){
// var obj={name:name,age:age}
// 如果变量名与属性名相同时,可以使用下面的方法
// var obj={name,age}
// return obj
// 因为每次返回的都是新对象 新的引用地址
return {
name,
age
}
}
var o=getObj("谢天",30)
var o1=getObj("谢天",30)
console.log(o===o1)
9.2单例模式
例:var instance
function getInstance(){
return instance || {name:'谢天',age:30}
}
var o=getInstance()
var o1=getInstance()
console.log(o===o1)
例:var instance
function getInstance(){
return instance || (instance={name:'谢天',age:30})
}
var o=getInstance()
var o1=getInstance()
console.log(o===o1)
9.3返回值的变种特征
例:function fn(f,a){
if(f(a)){
console.log("a");
}else{
console.log("b");
}
}
fn(function(a){
return a>10;
},5)
9.4小知识
new Error("错误信息")
new TypeError("类型错误信息"),比如应该是字符型,结果给了数值型,属于类型错误
new RangeError("范围错误")表示超出范围,比如要求是0-100,结果超出这个返回了
例.真值缩小
var arr=["零","一","二","三","四","五","六","七","八","九","十"];
function getCNNumber(num){
if(num<0 || num>=100) throw new RangeError("num是"+num+",这个数字超出范围,必须是0-100之间");
if(num<11) return arr[num];
if(num%10===0) return arr[num/10]+"十";
if(num<20) return "十"+arr[num%10];
return arr[~~(num/10)]+"十"+arr[num%10];
}
var n=getCNNumber(5);
var n=getCNNumber(10);
var n=getCNNumber(15);
var n=getCNNumber(20);
var n=getCNNumber(25);
console.log(n);
10.什么是回调
回调函数
+ 是一种函数的调用方式
+ 必然涉及到两个函数的使用(调用)
+ 有一个 函数A: 我们封装的函数, 在这里面可能封装了遍历或者异步
+ 有一个 函数B: 我们给到 函数A 的锦囊(目的: 我要做的事情)
+ 当调用 函数A 的时候, 把 函数B 当做实参传递进去
=> 函数A 的形参接受的就是 函数B 的存储地址
+ 说: 函数B 是 函数A 的回调函数
例:
回调函数的概念
我的封装代码
function A(fn) {
fn()
}
function B() {}
A(B)
私人解释:把一个函数作为参数传入到另外一个函数中,并在另外一个函数执行,叫做回调 (回调函数不能赋值 不能传参)
例:function fn(f){
f();
}
function fn1(){
console.log("aa")
}
fn(fn1);
1.封装遍历调用回调
function A(arr, fn) {
for (var i = 0; i < arr.length; i++) {
fn(arr[i], i, arr)
}
}
function B(item, index, arr) {
console.log('我是一个作为锦囊的函数', item, index, arr)
}
A([100, 200, 300, 400], B)
10.1回调的三种情况
1、异步时,通过回调,在异步完成后执行回调函数
2、当某件事件处理完成后调用回调函数
3、把条件作为内容分离或者把执行方式分离,通过回调函数完成
10.1.1异步后执行
例:setTimeout(timeHandler,1000);
function timeHandler(){
console.log("aaa")
}
10.1.2当某件事件处理完成后调用回调函数
例:function fn(a,b,f){
var s=a+b;
f(s);
}
function fn1(s){
console.log(s);
}
fn(5,7,fn1);
10.1.3把条件作为内容分离
例:function fn(f){
if(f(18)){
console.log("aa")
}else{
console.log("bb")
}
}
fn(function(a){
return a>10
})
10.1.4把执行方式分离
例:function fn(a,b,f){
return f(a,b);
}
function a(a,b){
return a+b;
}
function b(a,b){
return a-b;
}
function c(a,b){
return a*b;
}
function d(a,b){
return a/b
}
var s=fn(4,6,c);
console.log(s) //24
10.1.5两个函数之间互相调用完成递归的作用
例:var a=1;
function fn(f){
a++;
f(fn);
}
function fn1(f){
console.log(a);
if(a<3) f(fn1);
}
fn(fn1);
10.1.6回调地狱
回调地狱的原因是,当人们试图以一种从上到下的视觉方式执行JavaScript的方式编写JavaScript时
就是吊起来没完 就一直套
例:function showRed(fn1,fn2){
setTimeout(function(){
console.log("红灯");
fn1(fn2,showRed);
},2000)
}
function showYellow(fn1,fn2){
setTimeout(function(){
console.log("黄灯")
fn1(fn2,showYellow);
},1000)
}
function showGreen(fn1,fn2){
setTimeout(function(){
console.log("绿灯")
fn1(fn2,showGreen);
},1000)
}
showRed(showYellow,showGreen)
简写:就下面这种破造型
例:function showLight(){
setTimeout(function(){
console.log("红灯")
setTimeout(function(){
console.log("黄灯");
setTimeout(function(){
console.log("绿灯")
},2000);
},1000);
},2000);
}
showLight();
11.递归
例:
function fn(n) {
if (n === 1) return 1
return n * fn(n - 1)
}
// 将来我需要求 10 的阶乘 => fn(10)
// 将来我需要求 9 的阶乘 => fn(9)
// 求一个 4 的阶乘
var res = fn(4)
console.log(res)
递归=>在当前函数内调用自身函数
例:var a=1;
function fn(){
a++;
if(a<10) fn();
}
例:var a=1;
function fn(){
a++;
if(a<4) fn();
}
递归一般用于
1、深度遍历时
2、多次处理时
11.1 广度遍历 和 深度遍历
例: var obj = {
a:1,
b:2,
c: {
d:3,
f:{
g:5,
}
},
h:6
}
for(var key in obj){
console.log(key)
}
function showObjValue(obj){
for(var key in obj){
if(typeof obj[key]==="object"){
showObjValue(obj[key])
}else{
console.log(key,obj[key]);
}
}
}
showObjValue(obj);
11.2递归小案例
例:1.普通写法
var i=0;
var sum=0;
function getSum(){
i++;
sum+=i;
if(i<10) getSum();
}
getSum();
console.log(sum)
2.递归 求和 0-10 的求和
function getSum(i,sum){
i++;
sum+=i;
if(i<10) return getSum(i,sum);
return sum;
}
var s= getSum(0,0);
console.log(s);
function getSum(i,sum){
i++;
sum+=i;
if(i<10) sum=getSum(i,sum);
return sum;
}
var s= getSum(0,0);
console.log(s);

11.3求对象的最大深度(必考)
var obj = {
a:1,
b:{
c:{
d:{
e:{
f:{
g:{
}
}
}
}
}
},
aa:{
bb:{
cc:{
dd:1
}
}
}
};
function getMaxLv(obj, currentLv, maxLv) {
if (maxLv === undefined) maxLv = 1;
if (currentLv === undefined) currentLv = 1;
if (maxLv < currentLv) maxLv = currentLv;
for (var key in obj) {
if (typeof obj[key] === "object") {
maxLv = getMaxLv(obj[key], currentLv + 1, maxLv);
}
}
return maxLv;
}
var n = getMaxLv(obj);
console.log(n)
11.3 对象深比较 面试(必考)
对象深比较 只比较对象不比较数据类型 面试(必考)
准备: bool小开关 Object.keys(o1).length获得属性的数量 depthCompare中文深入比较
function depthCompare(o1,o2,bool){
if(bool===undefined) bool=true;
if(Object.keys(o1).length!==Object.keys(o2).length) return bool=false;
for(var key in o1){
if(typeof o1[key]==="object"){
bool=depthCompare(o1[key],o2[key],bool)
}else{
if(o1[key]!==o2[key]) return bool=false;
}
}
return bool
}
var obj={a:1,c:2,b:3,d:{e:10},f:{ss:11,dd:11}};
var obj1={a:1,b:3,c:2,f:{dd:11,ss:11},d:{e:10}};
var bool = depthCompare(obj,obj1);
console.log(bool)