js函数扩展内容---多参数,函数属性,字符串生成函数

1.多参数

在js中,Math.max()方法可以接受任意数量的参数,

javascript 复制代码
Math.max(1,2,3,4);//4
Math.max(1,2,3,4,5,6,7,8,9,10)//10

在max方法里面有一个rest参数,它接受了所有参数全部合成到了一个number数组里面,

javascript 复制代码
function rest(a,b,...arg){// 使用rest 参数时,必须放在参数列表的最后
  console.log(arg);
}

rest(1,2,3,4,5,6,7,8,9,10)//[3,4,5,6,7,8,9,10]

注意:使用rest 参数时,必须放在参数列表的最后

rest参数:类似扩展运算 ...,rest参数也使用...符号,但它的功能相反,在定义函数时使用,表示将多余的参数收集到一个数组中

和扩展运算区分开

  • 扩展运算:用于使用方法时,拆分数组或对象
  • rest参数 :用于定义方法时,合并参数

使用rest参数可以任意多个参数合成一个数组,并在函数内调用,理论上来说函数使用rest可以使用无数多个参数,

实现max方法

javascript 复制代码
// 对rest参数进行比较
function myMax(...args) {
  // 设置max接受最大值,初始值为第一个参数
  let max = args[0];
  // 遍历数组,如果当前值大于max,则将max设置为当前值
  args.forEach((item)=>{
    if(item>max){
      max=item;
    }
  })
  return max;
}
console.log(myMax(1,2,3,4,30,5,6,7,8,9,10));//30

2.函数属性

在js中函数也是对象,一个函数也能像对象一样设置属性,同时它还有一些默认属性

javascript 复制代码
console.dir(function name(){})

name

绝大部分函数都有name属性值,它存储了函数的名称

javascript 复制代码
function fn(){
  console.log(fn.name);
  return fn.name;
}

fn();//fn
console.log(fn());//fn fn
console.log(fn.name);//fn

值得注意的是,函数属性是绑定在函数对象上的,在函数体外也能访问

javascript 复制代码
// 对于赋值给变量的函数,函数本身是匿名的,函数name是变量名,
// 非匿名函数赋值,函数name是函数名
const f = function(){};
const fun = ()=>{}
const Fn = function F(){}

console.log(f.name);//f
console.log(fun.name);//fun
console.log(Fn.name);//F

对于赋值给变量的函数,函数本身是匿名的,函数name是变量名,非匿名函数赋值,函数name是函数名,

没有name属性值的情况

javascript 复制代码
// 没有name属性值
const fArr = [function(){}]
console.log(fArr[0].name);//''

length

函数的length属性表示了函数形参的个数,但是不包括rest参数

javascript 复制代码
function fa(a,b,c,...arg){
  console.log(fa.length);
  return fa.length;
}
console.log(fa.length);//3
fa(1,2,3,4,5,6,7,8,9,10);//3,和实参数量无关

要注意和argments的length区分开

  • function.length:表示的是函数除了rest参数外的形参数量,定义函数时的普通参数个数
  • argments.length:表示使用函数时的实参数量,使用函数传入的参数个数

自定义函数属性

除了默认的属性,还可以自定义函数的属性

javascript 复制代码
function add(){  
  return add.count++;
}

add.count = 0;
console.log(add(),add(),add(),add());//0 1 2 3

设置函数属性,可以重写一个闭包结构,关于闭包可以参考:

js闭包------简单理解闭包含义_js 闭包累加-CSDN博客

javascript 复制代码
// 使用内置变量的闭包
function count(){
  let sum = 0;
  return function (){
    return sum++;
  }
}
const addSum = count();

console.log(addSum(),addSum(),addSum(),addSum());//0 1 2 3

// 使用函数属性的闭包
function c(){
  c.count = 0;
  return function (){
    return c.count++;
  }
}
const addCount = c();

console.log(addCount(),addCount(),addCount(),addCount());//0 1 2 3

都达到了累加的效果,但是它们的区别在于,闭包中的变量不能被外部访问,而函数属性可以被外部访问

javascript 复制代码
c.count = 20;
console.log(addCount());//20

注意:count++会先赋值在自增

3.字符串生成函数

使用字符串生成函数:接受一串字符串,将字符串转成函数,这常常在服务端返回脚本时的场景使用,

常规生成一个函数的方法有,function,new Function,

eval()

eval()将传入的字符串当做 JavaScript 代码进行执行,这是一个危险的api,容易被注入攻击,

javascript 复制代码
let str = `function newFn(){
  console.log('这是eval改变字符串新生成的函数')
}`

//eval()函数会将字符串作为JavaScript代码进行解析和执行
eval(str);
newFn();//这是eval改变字符串新生成的函数

new Function()

new Function()会将字符串转成函数体内容

javascript 复制代码
// new Function()() 也可以将字符串作为函数体进行解析和执行
new Function('console.log("这是new Function()改变字符串新生成的函数")')();//这是new Function()改变字符串新生成的函数
let newF= new Function('console.log("这是new Function()改变字符串新生成的函数")');
newF();//这是new Function()改变字符串新生成的函数

setTimeout()

setTimeout()会将字符串参数识别成函数执行,

javascript 复制代码
// 使用setTimeout()函数
setTimeout(
  `(function newFn(){
    console.log('这是setTimeout()改变字符串新生成的函数')
  })()`
);//这是setTimeout()改变字符串新生成的函数

第一个参数支持输入函数或者字符串,字符串会自动解析成js代码,第二个参数没有时会被塞到事件队列最前面等待执行,所有这是一个异步过程,

script标签

可以通过script标签的innerHTML属性将字符串转成函数,但是这种方法只能在浏览器种使用,node环境下是没有dom对象的

javascript 复制代码
// 使用script标签
const script = document.createElement('script');
script.innerHTML = `(function newFn(){
  console.log('这是script标签改变字符串新生成的函数')
})()`
document.body.appendChild(script);//这是script标签改变字符串新生成的函数

这是一个同步的代码,在setTimeout之前执行

总结

一共有以上4种方法将字符串改成函数

  • 异步: setTimeout()

  • 同步:eval() ,new Function(),script标签

完整代码以及运行结果展示

javascript 复制代码
// 1.多参数的函数,rest参数
Math.max(1,2,3,4);//4
Math.max(1,2,3,4,5,6,7,8,9,10)//10

// Math.max()方法可以接受任意数量的参数,
// 类似扩展运算符...,rest参数也使用...符号,但它在定义函数时使用,表示将多余的参数收集到一个数组中。
function rest(a,b,...arg){// 使用rest 参数时,必须放在参数列表的最后
  console.log(arg);
}

rest(1,2,3,4,5,6,7,8,9,10)//[3,4,5,6,7,8,9,10]

// 对rest参数进行比较
function myMax(...args) {
  // 设置max接受最大值,初始值为第一个参数
  let max = args[0];
  // 遍历数组,如果当前值大于max,则将max设置为当前值
  args.forEach((item)=>{
    if(item>max){
      max=item;
    }
  })
  return max;
}
console.log(myMax(1,2,3,4,30,5,6,7,8,9,10));//30

// 2.函数属性

console.dir(function name(){})

// name
function fn(){
  console.log(fn.name);
  return fn.name;
}

fn();//fn
console.log(fn());//fn fn
console.log(fn.name);//fn

// 对于赋值给变量的函数,函数本身是匿名的,函数name是变量名,
// 非匿名函数赋值,函数name是函数名
const f = function(){};
const fun = ()=>{}
const Fn = function F(){}

console.log(f.name);//f
console.log(fun.name);//fun
console.log(Fn.name);//F

// 没有name属性值
const fArr = [function(){}]
console.log(fArr[0].name);//''

// length
function fa(a,b,c,...arg){
  console.log(fa.length);
  return fa.length;
}
console.log(fa.length);//3
fa(1,2,3,4,5,6,7,8,9,10);//3,和实参数量无关

// 自定义函数属性

function add(){  
  return add.count++;
}

add.count = 0;
console.log(add(),add(),add(),add());//0 1 2 3

// 使用内置变量的闭包
function count(){
  let sum = 0;
  return function (){
    return sum++;
  }
}
const addSum = count();

console.log(addSum(),addSum(),addSum(),addSum());//0 1 2 3

// 使用函数属性的闭包
function c(){
  c.count = 0;
  return function (){
    return c.count++;
  }
}
const addCount = c();

console.log(addCount(),addCount(),addCount(),addCount());//0 1 2 3

c.count = 20;
console.log(addCount());//20

// 字符串生成函数

let str = `function newFn(){
  console.log('这是eval改变字符串新生成的函数')
}`

//eval()函数会将字符串作为JavaScript代码进行解析和执行
eval(str);
newFn();//这是eval改变字符串新生成的函数

// new Function()() 也可以将字符串作为函数体进行解析和执行
new Function('console.log("这是new Function()改变字符串新生成的函数")')();//这是new Function()改变字符串新生成的函数
let newF= new Function('console.log("这是new Function()改变字符串新生成的函数")');
newF();//这是new Function()改变字符串新生成的函数

// 使用setTimeout()函数
setTimeout(
  `(function newFn(){
    console.log('这是setTimeout()改变字符串新生成的函数')
  })()`
);//这是setTimeout()改变字符串新生成的函数

// 使用script标签
const script = document.createElement('script');
script.innerHTML = `(function newFn(){
  console.log('这是script标签改变字符串新生成的函数')
})()`
document.body.appendChild(script);//这是script标签改变字符串新生成的函数
相关推荐
西猫雷婶2 小时前
python学opencv|读取图像(十九)使用cv2.rectangle()绘制矩形
开发语言·python·opencv
蟾宫曲3 小时前
在 Vue3 项目中实现计时器组件的使用(Vite+Vue3+Node+npm+Element-plus,附测试代码)
前端·npm·vue3·vite·element-plus·计时器
秋雨凉人心3 小时前
简单发布一个npm包
前端·javascript·webpack·npm·node.js
liuxin334455663 小时前
学籍管理系统:实现教育管理现代化
java·开发语言·前端·数据库·安全
qq13267029403 小时前
运行Zr.Admin项目(前端)
前端·vue2·zradmin前端·zradmin vue·运行zradmin·vue2版本zradmin
码农W3 小时前
QT--静态插件、动态插件
开发语言·qt
ke_wu3 小时前
结构型设计模式
开发语言·设计模式·组合模式·简单工厂模式·工厂方法模式·抽象工厂模式·装饰器模式
code04号3 小时前
python脚本:批量提取excel数据
开发语言·python·excel
小王爱吃月亮糖3 小时前
C++的23种设计模式
开发语言·c++·qt·算法·设计模式·ecmascript
hakesashou4 小时前
python如何打乱list
开发语言·python