JavaScript函数的内部属性——arguments、apply和call

在JavaScript函数内部,有两个特殊的对象: argumentsthisarguments 是一个类数组对象,包含传入函数中的所有对象。 arguments 还有一个 callee 的属性,该属性是一个指针,指向拥有这个 arguments 对象的函数。

arguments

首先来看一个经典的阶乘函数

function factorial(num) {
    if (num <= 1) {
        return 1;
    } else {
        return num * factorial(num - 1);
    }
}

由于JavaScript中的函数是对象,其存在被重新复制的风险,所以此时我们可以使用 arguments.callee 来进行递归调用,这样就可以做到函数的执行和函数名解耦。

function factorial(num) {
    if (num <= 1) {
        return 1;
    } else {
        return num * arguments.callee(num - 1);
    }
}

var trueFactorial = factorial;

factorial = function () {
    return 0;
};

console.log(factorial(5)); // 0
console.log(trueFactorial(5)); // 120

注:查询MDN得知,这一特性已经过时,不推荐大家使用,仅作为了解使用。

this

this 引用的是函数执行的环境对象(在网页的全局作用域中调用函数时,this对象引用的是window)

window.color = 'red';

function sayColor() {
    console.log(this.color);
}

sayColor();

var o = {color: 'blue'};
o.sayColor = sayColor;
o.sayColor();

call

callapply 都是函数非继承来的方法,其用途都是在特定的作用域中调用函数,实际上等于设置函数体内this对象的值。 callapply 唯一不同的地方在于 call 必须将所有参数单独传入,apply 可以传入数组或者 arguments

可以看一下代码示例了解call的用法

window.color = "red";
var o = { color: "blue" };
 
function sayColor(){
    alert(this.color);
}
 
sayColor();            //red
 
sayColor.call(this);   //red
sayColor.call(window); //red
sayColor.call(o);      //blue

可以实现链式构造器(chain constructor)

function Product(name, price) {
  this.name = name;
  this.price = price;
}

function Food(name, price) {
  Product.call(this, name, price);
  this.category = 'food';
}

console.log(new Food('cheese', 5).name);
// expected output: "cheese"

call 可以绑定 thisobj

function greet() {
  var reply = [this.animal, 'typically sleep between', this.sleepDuration].join(' ');
  console.log(reply);
}

var obj = {
  animal: 'cats', sleepDuration: '12 and 16 hours'
};

greet.call(obj);  // cats typically sleep between 12 and 16 hours
console.log(Math.max(1, 2, 3, 5, 6,));

var vaules = [1, 2, 3, 3, 4, 5, 6, 7, 12];
console.log(Math.max.apply(Math, vaules));

以上案例都来自参考中的链接,这里只举出部分重要例子,详细读者可以参阅文档。

参考

Function.arguments
Function.prototype.call()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值