Function::apply 方法

Function.apply()详解
本文详细介绍了JavaScript中的Function.apply()方法,解释了如何使用此方法来调用一个函数,并指定该函数内部this关键字所指向的对象。此外,还展示了如何利用apply方法实现对象之间的属性继承。

METHOD: Function::apply

--------------------------------------------------------------------------------
Function.apply(thisObj[, argArray])

apply 方法允许调用某一个对象的一个方法,并且用指定的一个对象替换当前的对象.

参数
thisObj
可选项。将被用作当前对象的对象。
argArray
可选项。将被传递给该函数的参数数组。

The apply method allows you to call a function and specify what the keyword this will refer to within the context of that function. The thisArg argument should be an object. Within the context of the function being called, this will refer to thisArg. The second argument to the apply method is an array. The elements of this array will be passed as the arguments to the function being called. The argArray parameter can be either an array literal or the deprecated arguments property of a function.

The apply method can be used to simulate object inheritance as in the following example. We first define the constructor for an object called Car which has three properties. Then the constructor for a second object called RentalCar is defined. RentalCar will inherit the properties of Car and add one additional property of its own - carNo. The RentalCar constructor uses the apply method to call the Car constructor, passing itself as thisArg. Therefore, inside the Car function, the keyword this actually refers to the RentalCar object being constructed, and not a new Car object. By this means,the RentalCar object inherits the properties from the Car object.

以下的例子用 apply 方法模拟一个对象的继承.第一先定义一个Car对象的构造方法,有三个属性.第二再定义一个RentalCar对象的构造方法,RentalCar将继承Car的属性并加上一个自己的属性carNo. RentalCar构造方法使用 apply 方法去调用Car的构造方法,把自身当作thisArg参数传递过去.因此,在Car函数的内部,关键字 this 实际上已经被 RentalCar 对象代替,并不是一个新的 Car 对象.通过这个方法,RentalCar对象从Car对象继承了它的属性.


Code:
function Car(make, model, year)
{
this.make = make;
this.model = model;
this.year = year;
}

function RentalCar(carNo, make, model, year)
{
this.carNo = carNo;
Car.apply(this, new Array(make, model, year));
}

myCar = new RentalCar(2134,"Ford","Mustang",1998);
document.write("Your car is a " + myCar.year + " " + myCar.make + " " + myCar.model + ".") ;

Output:
Your car is a 1998 Ford Mustang.

NOTE: The apply method is very similar to the call method and only differs in that, up until now, you could use the deprecated arguments array as one of its parameters.

NOTE: apply 方法非常像 call 的方法,唯一的区别是 apply 方法传递的参数是 arguments 或 Array 对象

ps:网上找的一篇介绍关于apply的文章,顺便学习一下英语,呵呵,就翻译出来,第一次翻译文章,如果有什么不对的地方,请多指教

原帖地址:http://blog.youkuaiyun.com/cinnxu/archive/2004/12/17/219503.aspx

### TypeError: fn.apply is not a function 的原因分析 `fn.apply is not a function` 这种错误通常发生在尝试调用 `apply()` 方法时,而目标对象实际上不是一个有效的函数。JavaScript 中的 `.apply()` 是用于改变函数上下文并传递参数数组的方法[^1]。 #### 原因可能包括以下几种情况: 1. **变量未正确定义为函数** 如果将非函数类型的值赋给某个变量,并试图对该变量使用 `.apply()`,就会抛出此错误。例如: ```javascript let nonFunction = null; nonFunction.apply(null, []); // 抛出 TypeError: Cannot read properties of null (reading 'apply') ``` 2. **动态绑定中的问题** 当通过某些方法(如 `bind()` 或者其他方式)创建新的函数实例时,如果传入的初始值不是合法的函数,则可能导致该错误。例如,在绑定过程中传入了非法参数[^3]: ```javascript const obj = {}; const boundFunc = Function.prototype.bind.call(obj); boundFunc(); // 抛出 TypeError: fn.apply is not a function ``` 3. **Promise 链接处理不当** 在 Promise 使用场景下,`.then()` 接收两个回调分别对应成功和失败的情况。但如果其中一个被赋予了一个非函数值也会引发类似的异常: ```javascript const p = Promise.resolve('success'); p.then(undefined, undefined); // 不会报错但无意义操作 p.then({}, {}); // 将导致 TypeError because object is not callable. ``` --- ### 解决方案 针对以上提到的各种可能性提供相应的修复措施如下所示: #### 方案一:确认所使用的变量确实是一个函数 在实际开发环境中应该始终验证任何即将执行的操作符是否具备预期的功能特性之前先做类型检查: ```javascript if(typeof someVariable === 'function'){ someVariable.apply(context,args); }else{ throw new Error(`${someVariable} is not a valid function`); } ``` #### 方案二:修正 bind 调用逻辑 确保当利用 `Function.prototype.bind` 创建新函数的时候所提供的第一个参数即 thisArg 正确指向一个可调用的对象或者原始函数本身而不是单纯的普通数据结构比如数字字符串布尔等等: 修改后的例子应该是这样的形式: ```javascript const originalFn = () => console.log("Original Function Called"); let contextObj = {}; // Correct Usage let correctBoundFn = originalFn.bind(contextObj); correctBoundFn(); ``` #### 方案三:合理配置 promise then 方法内的处理器 对于 promises 来说要特别注意不要随便塞进去不符合标准定义的东西作为其完成态或者是拒绝态下的响应机制的一部分. 应该像这样写才合适: ```javascript p.then( value => { console.log(`Resolved with ${value}`); }, reason => { console.error(`Rejected due to ${reason.message || reason}`); } ); ``` --- ### 总结说明 综上所述,“TypeError: fn.apply is not a function”的根本原因是由于尝试对那些并非真正意义上的 JavaScript 函数实体进行了 apply 操作所致。因此只要遵循良好的编程习惯——提前做好必要的输入校验工作就可以有效规避此类潜在隐患的发生。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值