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

1.多参数

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

Math.max(1,2,3,4);//4
Math.max(1,2,3,4,5,6,7,8,9,10)//10

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

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方法

// 对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中函数也是对象,一个函数也能像对象一样设置属性,同时它还有一些默认属性

console.dir(function name(){})

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是变量名,非匿名函数赋值,函数name是函数名,

没有name属性值的情况

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

length

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

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:表示使用函数时的实参数量,使用函数传入的参数个数

自定义函数属性

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

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

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

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

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

// 使用内置变量的闭包
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

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

3.字符串生成函数

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

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

eval()

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

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

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

new Function()

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

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

setTimeout()

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

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

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

script标签

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

// 使用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标签

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

// 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标签改变字符串新生成的函数

  • 28
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值