【JS】关于call()方法中的this
在网上看到这样一段代码:
实现继承function Animal(name){
this.name = name;
this.showName = function(){
alert(this.name);
}
}
function Cat(name){
Animal.call(this, name);
}
var cat = new Cat("Black Cat");
cat.showName();
Animal.call(this) 的意思就是使用 Animal对象代替this对象,那么 Cat中不就有Animal的所有属性和方法了吗,Cat对象就能够直接调用Animal的方法以及属性了.
对于其中一句话不是很理解:“ Animal.call(this) 的意思就是使用 Animal对象代替this对象”。
我在犀牛书中看到,call()和apply()的第一个参数是要调用函数的母对象,它是调用上下文,函数体内通过this来获得它的引用。
在上面代码中,Animal是要调用的函数,而它没有被封装作为某个对象的属性,那么Animal的母对象不就是global对象吗?为何代码中的解释却是this指向Animal对象呢?
回答
好吧,我们首先来看下new
做了什么:
根据我选中部分的描述,我们知道new Cat("Black Cat")
之后,Cat
里面的this
关键字,就指向了Cat
实例本身。
然后再来看call
又是怎么回事:
仍然注意我选中的部分,thisArg
(你的例子中就是Animal.call(this, name)
里的this
),fun
(你的例子中就是Animal.call(this, name)
里的Animal
)。
由此我们对Animal.call(this, name)
这句话,可以知道两点:
她会执行
Animal
方法,并传入name
作为参数Animal
方法里写的this
会被call(this
里的this
(实际是Cat
实例对象,上面刚讲的)替换掉
那你再想想,Animal
方法里写的this.name = name;
和this.showName = function(){ alert(this.name); }
是什么意思?其实就是cat.name = name;
和cat.showName = function(){ alert(cat.name); }
现在再看到cat.showName();
居然能弹出来Black Cat
,还会吃惊么?
这个说法是错误的
Animal.call(this) 这里的this
指的是new出来的Cat对象
这样调用的作用是让Animal函数内部的this
指向call()函数的第一个参数this
,也就是new出来的Cat对象
换句话说,fun.call(thisArg, ...) 是让thisArg这个对象临时具有fun函数这个属性并调用执行
这会儿犀牛书不在手边,无法去核实原文。我建议你还是先看看别的资料里对 call
和 apply
的解释,因为你所说的“母对象”并不是你自己理解的这个意思。事实上“母对象”这个翻译很奇怪,我很怀疑犀牛书的译者会写出这么个不着调的名字来,again 此时无法去核实,自己查吧,推荐去看 MDN。
1.this变量在函数执行的时候有指向,指向当前函数执行上下文-函数执行所以来的对象
2.当通过new操作符来实例化构造函数时,此时this的指向为这个实例化对象,在构造函数执行完毕后,返回这个实例对象(可以省略return this语句,或有return语句,但是返回值为基本类型时,也返回this。除了return一个对象时,就返回这个对象而不是this)
3.函数的call和apply方法可以调用执行函数并能够改变函数执行时的this指向
function Animal(name){ //Fun_Animal this.name = name;
this.showName = function(){
console.log(this.name);
}
}
Animal
只是一个普通函数,当使用new操作符时,其才从语义上变成一个对象的构造函数。
如下代码可以调用,只是此时的this因为没有特别指定,name和showName变成了一个全局变量
Animal('DOG'); console.log(name);//DOG
console.log(showName());//DOG
function Cat(name){ //Fun_Cat Animal.call(this, name);
}
Cat('cat');
console.log(name);//cat
console.log(showName());//cat
Cat
也是如此,作为普通函数调用时,this也是指向全局对象,覆盖了之前Animal的执行结果
以上是不使用new操作符的情况
在使用new操作符的情况下
var cat = new Cat("Black Cat");
Cat函数作为构造函数被调用,此时的this指向以Cat为构造函数的实例对象cat_instance;Animal.call(this, name);
语句被执行,Animal
是一个普通函数;
Animal函数被执行,this为Animal.call调用时传入的cat_instance,为这个对象添加name和showName属性,执行完毕后返回;
new操作符返回cat_instance给cat变量
至此,Cat构造函数通过Animal.call的调用初始化了其父类的构造函数
有这方面的笔记如下
apply and call
call方法 改变上下文环境
var files = [...]xx = [].slice.call(files)
files截取了[]的slice方法 在slice方法内部如果有this指针项,this都指向files
xx是所截取的slice的返回值,因为参数列表中(files, ) 只有files,省略了slice的参数,没有其他所以截取了整个数组
所以xx.length = files.length
如果 xx = [].slice.call(files,0,1)
则xx的值只有files的第一个元素
apply的用法差不多 但是他还有一个特性,就是将传入的数组参数转化成参数列表
apply(this, [1,2,3,4]) ==> apply(this, 1, 2, 3, 4)
math.max(1,2,3,4)
正确的使用方式
例如math.max([1,2,3,4])
这样是不支持的
apply ==> Math.max.apply(this, [1,2,3,4]) => Math.max.apply(this,1,2,3,4) ok
我是看了好几遍你的问题,真的好绕啊。楼上说的很对,其实就先不要管什么母对象,什么对象替换对象。就只想,this就是一个指针,最开始是指向window的(当然严格模式下,是指向undefined)。函数定义并不会涉及this,只有在函数调用的时候才会。回到你的代码,cat.showName();函数执行,this的指向是发生变化的,那就看一下,是怎么变化的。
this会先指向cat(这里还有一个坑,是因为new构造函数让this指向了cat),进入cat函数后,Animal.call(this, name);这句话又改变了this的指向,又指向了Animal。这个过程很清楚了吧。其余的知识,还是看一些文章吧,有关于this的指向详细的解释。
谢谢邀请,太忙没来得及看。解决了就好
根据《高程》,new运算符干了4件事:
1.创建一个空对象;
2.将构造函数的作用域赋给新对象;
3.运行函数;
4.返回新对象;
call,apply的作用类似2,只不过传的不是构造函数,而是你指定的那个参数的作用域;
你贴的这段代码,是典型的构造函数继承;
看看这样回答好不好:Animal.call("某个对象", name);
首先Animal是个函数,现在要调用这个函数,不过在传递name参数之外要额外做一件事情:
告诉Animal函数,你执行时的this是"某个对象"。
你看我这里把this替换为"某个对象",以免混淆。
你这里的Animal函数,是存在你说的那个问题的,如果直接运行这个函数,global就会生成一个name变量和一个showme函数。
如果跳脱开面向对象,从实际数据存储的角度看就会清晰很多。
以上是 【JS】关于call()方法中的this 的全部内容, 来源链接: utcz.com/a/86753.html