目录
(2)方法二:通过.Array.prototype.slice.call(arguments,index)
1、arguments
arguments是一个类数组对象,主要作用是保存函数的参数,包含着传入函数中的所有参数,因此,JS(ECMAScript)函数的参数与其他语言函数的参数不同,js函数不介意传递参数的个数和类型,这些函数的参数均保存在arguments这个类数组中。
function arr(a,b,c,d){
console.log(arguments);//类数组对象[Arguments]{ '0': 1, '1': 2, '2': 3, '3': 4, '4': 5 }
console.log(arguments.length);//5
}
arr(1,2,3,4,5);
如何将类数组对象转换为数组
(1)方法一:通过Array.from()
function arr(a,b,c,d){
console.log(arguments);//类数组对象[Arguments]{ '0': 1, '1': 2, '2': 3, '3': 4, '4': 5 }
console.log(Array.from(arguments));//[ 1, 2, 3, 4, 5 ]
}
arr(1,2,3,4,5);
(2)方法二:通过.Array.prototype.slice.call(arguments,index)
function arr(a,b,c,d){
//Array.prototype.slice.call(arguments,index)
// index下标 表示类数组对象转化为数组的起点
console.log(Array.prototype.slice.call(arguments,0));//[1,2,3,4,5]
console.log(Array.prototype.slice.call(arguments,1));//[2,3,4,5]
}
arr(1,2,3,4,5);
(3)...拓展运算符
function arr(a,b,c,d){
console.log(arguments);//类数组对象[Arguments]{ '0': 1, '1': 2, '2': 3, '3': 4, '4': 5 }
let arr=[...arguments];
console.log(arr); //[ 1, 2, 3, 4, 5 ]
}
arr(1,2,3,4,5);
arguments还有一个名为callee的属性,该属性是一个指针,指向拥有这个arguments对象的函数,仅在相关函数正在执行时才可用,callee 属性的初始值就是正被执行的函数对象。
//实现匿名的递归函数
var sum = function (n) {
if (n <= 1) {
return 1;
} else {
return n + arguments.callee(n - 1);
}
}
console.log(sum(6));//21
2、this
this不仅是函数的内部属性,也可以在函数的外部使用。在Js中this会随着执行环境的改变而改变。简单来说谁调用了这个方法,this就指向谁
(1)单独使用
node环境下单独使用this
在全局作用域使用this,this指向的是空对象
console.log(this); //{}
在局部作用域使用this,this指向的是全局对象 global
function foo() {
console.log(this); //指向全局对象global <ref *1> Object [global] {......}
}
foo()
浏览器环境下单独使用this
<body>
<script>
// 在浏览器环境下 this单独使用 指向的就是window对象
console.log(this);
function foo() {
console.log(this);
}
foo()
</script>
</body>
(2)函数中使用
在函数中,函数的所属者默认绑定到 this 上。在浏览器中,this指向全局对象window,在node中,指向的就是global全局对象,因为函数是局部作用域。
function foo() {
return this;
}//局部作用域 this 指向的就是全局对象global
foo();
(3)在事件中使用
<button onclick="this.style.display='none'"> 点我 </button>
<--! onclik点击事件 点击后按钮就会消失 -->
(4)显示函数绑定
在 JavaScript 中函数也是对象,对象则有方法,apply 和 call 就是函数对象的方法,他们允许切换函数执行的上下文环境(context),即 this 绑定的对象。
call(执行环境对象,实参列表 ):
b.call(obj,参数) 调用call方法,第一个参数就是要把b添加到哪个环境中,即第一个参数就是this指向的那个对象。
//call 改变this的指向 call(执行环境对象,实参列表);
var person1 = {
sayName: function (a) {
console.log(this.name + a);
}
}
var person2 = {
name:'terry'
}
person1.sayName.call(person2, 123)//执行函数结果:terry123
//在使用call调用的时候,可以传递多个参数
//只传一个参数obj(执行环境对象)时
var obj = {
name: 'zhangsan',
sayName: function () {
console.log(this.name);
}
}
var b = obj.sayName
b.call(obj) //执行函数结果:zhangsan
//传两个参数
var obj = {
name: 'zhangsan',
sayName: function (a) {
console.log(this.name + a);
}
}
var b = obj.sayName
b.call(obj,123) //执行函数结果:zhangsan123
//传三个参数时
var obj = {
name: 'zhangsan',
sayName: function (a,b) {
console.log(this.name,a,b);
}
}
var b = obj.sayName
b.call(obj,1,2) //执行函数结果:zhangsan 1 2
apply(执行环境对象,实参列表数组)
调用apply方法与call方法类似,apply也可以有多个参数,但是不同的是,第二个参数必须是一个数组
var obj = {
name: 'zhangsan',
sayName: function (a) {
console.log(this.name,a);
}
}
var b = obj.sayName;
b.apply(obj,100);// 100不是数组,报错,第二个参数必须是数组
var obj = {
name: 'zhangsan',
sayName: function (a) {
console.log(this.name,a);
}
}
var b = obj.sayName;
b.apply(obj,[100]); //函数执行结果: zhangsan 100
var obj = {
name: 'zhangsan',
sayName: function (a,b) {
console.log(this.name);
}
}
var b = obj.sayName;
b.apply(obj,[100,200]);//函数执行结果:zhangsan 100 200
//区别: b.call(obj,100,200) 执行结果相同