关于apply和call的一点记录

本文解析了JavaScript中this的工作原理及其与apply、call的关系。通过实例演示如何使用这两个方法来改变函数执行上下文,实现代码复用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    JavaScript高级知识里面,原型链,apply,call这些都陆陆续续在看,但是一直迷迷糊糊,反省了一下是因为自己只是看而没有去理解,记录,所以从现在开始记录一下学到的(估计也是到处复制粘贴别人的...),以后发现记录有错还能回来改正,希望早日理解JavaScript高级知识。

MDN中查看:Function.prototyle.apply(obj, args):apply接收2个参数,obj指的是在函数运行时指定的this,但是指定的this值不一定是函数执行的真正的this值,如果函数处于

非严格模式下(严格模式:‘"use strict"),当obj为null或者undefined使指向全局对象,同时值为原始值的this会指向原始值(数字,字符串,布尔值)的自动包装对象。

MDN里面描述了apply的作用,对于理解这个函数很重要:

在调用一个存在的函数时,你可以为其指定一个 this 对象。 this 指当前对象,也就是正在调用这个函数的对象。 使用 apply, 你可以只写一次这个方法然后在另一个对象中继承它,而不用在新对象中重复写该方法。

字面意思可以理解,但是还是感觉不够具体,于是去搜索了一下,发现知乎有个回答很简洁点击打开链接

明白this 是个参数,然后就好理解了:普通的函数调用隐式传入 this,call 和 apply 可以显式指定它

function cat(){

}
cat.prototype = {
food:"fish",
say:function(){
alert("I LOVE "+this.food);
}
}
var blackCat = new cat;
blackCat.say();

但是如果我们有一个对象whiteDog = {food:"bone"},我们不想对它重新定义say方法,那么我们可以通过call或apply用blackCat的say方法:blackCat.say.call(whiteDog);

所以,可以看出call和apply是为了动态改变this而出现的,当一个object没有某个方法,但是其他的有,我们可以借助call或apply用其它对象的方法来操作。

由此可以看出,blackCat.say.call(whiteDog)是以whiteDog为this执行blackCat.say方法。所以上述代码运行结果是先弹出"I LOVE fish"再弹出"I LOVE bone", 突然有一点领悟了哈。

这里还有一个操作DOM的例子,也是来自知乎:

call和apply可以用来重新定义函数的执行环境,也就是this的指向。通过一个操作DOM的例子来理解。

function changeStyle(attr, value){
    this.style[attr] = value;
}
var box = document.getElementById('box');
window.changeStyle.call(box, "height", "200px");

call中的第一个参数用于指定将要调用此函数的对象,在这里,changeStyle函数将被box对象调用,this指向了box对象,如果不用call的话,程序报错,因为window对象中没有style属性。

apply的用法:

window.changeStyle.apply(box, ['height', '200px']);

apply接受的是数组参数,call接受的是连续参数。

先大概记录这些吧。

2018-3-1更新

function Pet(words) {
    this.words = words;
    this.speak = function () {
        console.log(this.words);
    }
}


function Dog(words) {
        Pet.call(this, words);
        //Pet.apply(this, arguements);
}


var dog = new Dog('Wang');

dog.speak();

看到这样一段代码,对Pet.call(this, words);暂时无法参透,记录一下以后理解了更新。


D:\anaconda\envs\mamba\python.exe E:\ultralytics-v8.3.63\ultralytics\models\yolo\pwcmamba\ceshi.py 使用设备: cuda 解析第0层,from=-1,当前ch列表长度=1 解析第1层,from=-1,当前ch列表长度=1 解析第2层,from=-1,当前ch列表长度=2 解析第3层,from=-1,当前ch列表长度=3 解析第4层,from=-1,当前ch列表长度=4 解析第5层,from=-1,当前ch列表长度=5 解析第6层,from=-1,当前ch列表长度=6 解析第7层,from=-1,当前ch列表长度=7 解析第8层,from=-1,当前ch列表长度=8 解析第9层,from=-1,当前ch列表长度=9 解析第10层,from=-1,当前ch列表长度=10 解析第11层,from=-1,当前ch列表长度=11 解析第12层,from=[-1, -6],当前ch列表长度=12 解析第13层,from=-1,当前ch列表长度=13 解析第14层,from=-1,当前ch列表长度=14 解析第15层,from=-1,当前ch列表长度=15 解析第16层,from=[-1, -12],当前ch列表长度=16 解析第17层,from=-1,当前ch列表长度=17 解析第18层,from=-1,当前ch列表长度=18 解析第19层,from=[-1, -6],当前ch列表长度=19 解析第20层,from=-1,当前ch列表长度=20 解析第21层,from=-1,当前ch列表长度=21 解析第22层,from=[-1, -13],当前ch列表长度=22 解析第23层,from=-1,当前ch列表长度=23 解析第24层,from=[17, 20, 23],当前ch列表长度=24 Traceback (most recent call last): File "E:\ultralytics-v8.3.63\ultralytics\models\yolo\pwcmamba\ceshi.py", line 15, in <module> model = YOLO(cfg_path) File "E:\ultralytics-v8.3.63\ultralytics\models\yolo\model.py", line 23, in __init__ super().__init__(model=model, task=task, verbose=verbose) File "E:\ultralytics-v8.3.63\ultralytics\engine\model.py", line 144, in __init__ self._new(model, task=task, verbose=verbose) File "E:\ultralytics-v8.3.63\ultralytics\engine\model.py", line 255, in _new self.model = (model or self._smart_load("model"))(cfg_dict, verbose=verbose and RANK == -1) # build model File "E:\ultralytics-v8.3.63\ultralytics\nn\tasks.py", line 334, in __init__ m.stride = torch.tensor([s / x.shape[-2] for x in _forward(torch.zeros(1, ch, s, s))]) # forward File "E:\ultralytics-v8.3.63\ultralytics\nn\tasks.py", line 332, in _forward return self.forward(x)[0] if isinstance(m, (Segment, Pose, OBB)) else self.forward(x) File "E:\ultralytics-v8.3.63\ultralytics\nn\tasks.py", line 110, in forward return self.predict(x, *args, **kwargs) File "E:\ultralytics-v8.3.63\ultralytics\nn\tasks.py", line 128, in predict return self._predict_once(x, profile, visualize, embed) File "E:\ultralytics-v8.3.63\ultralytics\nn\tasks.py", line 149, in _predict_once x = m(x) # run File "D:\anaconda\envs\mamba\lib\site-packages\torch\nn\modules\module.py", line 1518, in _wrapped_call_impl return self._call_impl(*args, **kwargs) File "D:\anaconda\envs\mamba\lib\site-packages\torch\nn\modules\module.py", line 1527, in _call_impl return forward_call(*args, **kwargs) File "E:\ultralytics-v8.3.63\ultralytics\nn\modules\block.py", line 1293, in forward x = self.ea_vss(x) File "D:\anaconda\envs\mamba\lib\site-packages\torch\nn\modules\module.py", line 1518, in _wrapped_call_impl return self._call_impl(*args, **kwargs) File "D:\anaconda\envs\mamba\lib\site-packages\torch\nn\modules\module.py", line 1527, in _call_impl return forward_call(*args, **kwargs) File "E:\ultralytics-v8.3.63\ultralytics\nn\modules\block.py", line 1265, in forward mamba_out.append(self.mamba(head_data)) File "D:\anaconda\envs\mamba\lib\site-packages\torch\nn\modules\module.py", line 1518, in _wrapped_call_impl return self._call_impl(*args, **kwargs) File "D:\anaconda\envs\mamba\lib\site-packages\torch\nn\modules\module.py", line 1527, in _call_impl return forward_call(*args, **kwargs) File "D:\anaconda\envs\mamba\lib\site-packages\mamba_ssm\modules\mamba_simple.py", line 146, in forward out = mamba_inner_fn( File "D:\anaconda\envs\mamba\lib\site-packages\mamba_ssm\ops\selective_scan_interface.py", line 306, in mamba_inner_fn return MambaInnerFn.apply(xz, conv1d_weight, conv1d_bias, x_proj_weight, delta_proj_weight, File "D:\anaconda\envs\mamba\lib\site-packages\torch\autograd\function.py", line 539, in apply return super().apply(*args, **kwargs) # type: ignore[misc] File "D:\anaconda\envs\mamba\lib\site-packages\torch\cuda\amp\autocast_mode.py", line 113, in decorate_fwd return fwd(*args, **kwargs) File "D:\anaconda\envs\mamba\lib\site-packages\mamba_ssm\ops\selective_scan_interface.py", line 181, in forward conv1d_out = causal_conv1d_cuda.causal_conv1d_fwd(x, conv1d_weight, conv1d_bias, None, True) RuntimeError: Expected x.is_cuda() to be true, but got false. (Could this error message be improved? If so, please report an enhancement request to PyTorch.)
最新发布
08-17
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值