javascript 将 call 函数赋值给变量后调用报错?
PHP中文网
PHP中文网 2017-04-10 14:28:36
[JavaScript讨论组]

无意间写到了些javascript代码,遇到了不明白的地方,求解释:

 var a = [2,3,3,1,7,5];
 var b = [2,3,3,1,7,5];
 var fn = Array.prototype.sort;
  fn.call(a);

这里可以成功处理数组a;
但是,如果这样用:

var fn1 = Array.prototype.sort.call;
fn1(b);

这里就报错了。

undefined is not a function指的是什么?

fn1 //可以输出 function call(){[native code]}

PHP中文网
PHP中文网

认证0级讲师

全部回复(1)
天蓬老师

我写一下Function.prototype.call的伪代码好了

Function.prototype.call = function(newThis) {
  var targetFn = this;//注意这里,call的目标函数是通过this拿到的
  var args = Array.prototype.slice.call(arguments, 1);

  return targetFn.[[Call]] (this = newTHis, arguments = args);//[[Call]]是function的内部方法
}

题主做了fn = xxx.call之后(其实原型链结算后等价于fn = Function.prototype.call),call内部拿到的所谓“targetFn”相当于丢失了。也就是fn虽然存在,但执行进入fn的"Native Code"中的时候拿不到要实际执行的函数了,参考ECMA规范中Function.prototype.call的第一步

If IsCallable(func) is false, then throw a TypeError exception.

所以这个错误抛出是符合规范的


我再写几个例子看看能不能加深一下理解。其实这事的本质就是Function.prototype.call本身也是一个function,得按照javascript的function的所有规矩来办

function foo(a) {
  console.log('bar!', this, a);
}

function baz(b) {
  console.log('bla bla', this, b);
}

var fn = baz.call;
fn.call(foo, {c:1}, 1);//bar! {c: 1} 1 

baz.call.call(foo, {c:1}, 1);//bar! {c: 1} 1 

var fn2 = baz.call.bind(foo);
fn2({c:1}, 1);//bar! {c: 1} 1 
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号