arguments使用

6 篇文章 0 订阅
5 篇文章 0 订阅

arguments使用

arguments 是一个对应于传递给函数的参数的类数组对象
function fn() {
	console.log(arguments[0]) // aa
	console.log(arguments[1]) // bb
	console.log(arguments[2]) // cc
	argumnets[2] = 'new value'
	/**
	* {
	* 	0: 'aa',
	* 	1: 'bb',
	* 	2: 'new value',
	* 	length: 3 // 必须有length
	* }
	*/
	console.log(argumnets)
	// 转成正在的数组
	var args = Array.prototype.slice.call(arguments)
	var args2 = [].slice.call(arguments)
	// ES5
	var args3 = Array.from(arguments)
	var args4 = [...arguments]
	var args5 = Array.apply(null, arguments)
	console.log(args) // ['aa', 'bb', 'cc']
	console.log(args2) // ['aa', 'bb', 'cc']
	console.log(args3) // ['aa', 'bb', 'cc']
	console.log(args4) // ['aa', 'bb', 'cc']
	console.log(args5) // ['aa', 'bb', 'cc']
}
fn('aa','bb','cc')
对参数的使用
function test (a) {
  console.log(a, Object.prototype.toString.call(arguments)) // 1 [object Arguments]
  console.log(arguments[0], arguments[1]) // 1 undefined
  console.log(typeof arguments[0]) // number
}
test(1)
注意

警告:对参数使用slice会阻止某些JavaScript引擎中的优化;如果你关心性能,尝试通过遍历arguments对象来构造一个新的数组。

试例

  1. 遍历参数求和
function add() {
   var sum =0,
       len = arguments.length;
   for(var i=0; i<len; i++){
       sum += arguments[i];
   }
   return sum;
}
add()                           // 0
add(1)                          // 1
add(1,2,3,4);                   // 10
  1. 定义连接字符串的函数(这个例子定义了一个函数来连接字符串。这个函数唯一正式声明了的参数是一个字符串,该参数指定一个字符作为衔接点来连接字符串。该函数定义如下)
function myConcat(separator) {
var args = Array.prototype.slice.call(arguments, 1)
return args.join(separator)
console.log(myConcat(", ", "red", "orange", "blue")) // "red, orange, blue"
console.log(myConcat("; ", "elephant", "giraffe", "lion", "cheetah")) // "elephant; giraffe; lion; cheetah"
console.log(myConcat(". ", "sage", "basil", "oregano", "pepper", "parsley")) // "sage. basil. oregano. pepper. parsley"
}
  1. 剩余参数、默认参数和解构赋值参数
  1. 严格模式下, delete运算符后跟随非法标识符(即delete 不存在的标识符),会抛出语法错误; 非严格模式下,会静默失败并返回false
  2. 严格模式中,对象中定义同名属性会抛出语法错误; 非严格模式不会报错
  3. 严格模式中,arguments对象是传入函数内实参列表的静态副本;非严格模式下,arguments对象里的元素和对应的实参是指向同一个值的引用
  4. 严格模式不允许八进制整数直接量(如:023)
  5. 严格模式中,函数形参存在同名的,抛出错误; 非严格模式不会
  6. 严格模式中 eval和arguments当做关键字,它们不能被赋值和用作变量声明
  7. 严格模式会限制对调用栈的检测能力,访问arguments.callee.caller会抛出异常
  8. 严格模式 变量必须先声明,直接给变量赋值,不会隐式创建全局变量,不能用with
  9. 严格模式中 call apply传入null undefined保持原样不被转换为window
  10. 判断是否为严格模式,在函数内部打印this;非严格模式:函数的调用上下文(this)是全局对象(Window);严格模式:调用上下文(this)是undefined

// 'use strict' // 整个 js 都是严格模式
// arguments对象可以与剩余参数、默认参数和解构赋值参数结合使用。
function foo(...args) {
  // 'use strict' // 函数内是严格模式
  return args
}
console.log(foo(1, 2, 3)) // [1,2,3]

// 当非严格模式中的函数没有包含剩余参数、默认参数和解构赋值,那么arguments对象中的值会跟踪参数的值
function func(a) {
  arguments[0] = 99 // 更新了arguments[0] 同样更新了a
  console.log('a', a) 
}
func(10) // 99

function func2(a) {
  a = 88 // 更新了a 同样更新了arguments[0]
  console.log(arguments[0])
}
func2(10)  // 88
// -------------------------------------------------------------------------------------------------------------
// 当非严格模式中的函数有包含剩余参数、默认参数和解构赋值,那么arguments对象中的值不会跟踪参数的值(函数的参数有默认值)
function func3(a = 55) {
  arguments[0] = 99; // 更新 arguments[0] 不会同时更新 a
  console.log(a);
}
func3(10); // 10

function func4(a = 55) {
  a = 99; // 更新 a 不会同事更新 arguments[0]
  console.log(arguments[0]);
}
func4(11); // 11

function func5(a = 55) {
  console.log(arguments[0]);
}
func5(); // undefined
  1. 箭头函数
let slice = (arr) => Array.prototype.slice.call(arr);
var b ="12345678"
console.log(slice(b)) // [1,2,3,4,5,6,7,8]
  1. 定义创建HTML列表的方法
function list(type) {
  var result = '<' + type + 'l><li>'
  var args = Array.prototype.slice.call(arguments, 1)
  result += args.join('</li><li>')
  result += '</li></' + type + 'l>'
  return result
}

var listHTML = list('u', 'One', 'Two', 'Three')
console.log(listHTML) // <ul><li>One</li><li>Two</li><li>Three</li></ul>
  1. callee
function foo(a, b) {
  console.log(arguments.length) // 10 获取实参的个数
  console.log(arguments.callee.length) // 2 获取形参的个数
}
foo(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
  1. caller

调用当前正在执行函数 的函数
caller 是一个函数被另一个函数调用生成的,指向的是 调用者
如果函数没有被其他函数调用,或该函数是又顶层调用,那么 caller 为 null。
arguments.caller 已被弃用 所以用 arguments.callee

function c() {
  if (arguments.callee.caller) {
    console.log(arguments.callee.caller.toString()) // 函数 p 的文本
  } else {
    console.log('顶层调用')
  }
}
console.log(c.caller) // null
c() // 顶层调用(arguments.callee.caller 的值 为null)
function p() {
  c() // 函数 c 被函数 p 调用,这个时候的 arguments.callee.caller 的值 为函数 p 本身
}
p() // 函数 p 的文本

// ---------------------------------------------------
// 下方示例
function runCaller() {
  // 因为是顶级调用,又没有其他函数调用它,所以值为 null
  console.log('runCaller1:', runCaller.caller) // null
}

function runCaller2() {
  // runCaller2 也是顶级调用,但是在 callerChild2 内部有函数 callerChild 并且执行了 callerChild
  function callerChild() {
    console.log(callerChild.caller) // 因为是在runCaller2内部调用了它的 所以在这里的 caller 就指向 runCaller2 整个函数
  }
  // 
  callerChild()
}

function runCaller3() {
  callerChild()
}

function callerChild() {
  console.log(callerChild.caller) // 指向调用它的父级函数 runCaller3
}

runCaller()
runCaller2()
runCaller3()
  1. 通过改变 arguments.length 改变实参个数
function foo() {
  arguments.length = 2
  for (let i = 0; i < arguments.length; i++) {
    console.log(arguments[i])
  }
}
foo(3) // 3, undefined
foo(1, 2, 3) // 1, 2
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值