摘要:具体可参考下面代码定义到原型链上的方法这里没有继承父类中的方法张三张三太史公曰总结一下与兄弟俩的任务使用一个指定的值和若干个指定的参数值的前提下调用某个函数或方法。本篇人物小传自此结束。
家族世系在JavaScript中,有这么俩货,一个叫call,一个叫apply,它们俩工作几乎一毛一样,但是也有所区别,曾经对这个知识点非常困惑,看过几篇博客也没搞清楚这哥俩到底打算要干个啥,直到某天仔细研究过this关键词的相关知识点后,才恍然大悟,
这篇文章主要就是为call和apply兄弟俩写“人物传记”,希望能帮助到其他对这个问题有困惑的童鞋。
在正式介绍这哥俩之前,首先我们得知道兄弟二人到底是谁家的熊孩子,所以有必要熟悉一下哥俩的“家族世系”,刨根问底,以便日后开心地与兄弟二人愉快地玩耍交朋友。
call和apply是被定义到Function.prototype上的两个方法,也就是Function类型中的原生方法,早在ECMAScript标准的第一个版本中就已经被初步定义,历史悠久,所以现代浏览器几乎都支持,完全不必担心兼容性。
call方法与apply方法要实现的功能几乎一致,就是使用一个指定的this值和若干个指定的参数值的前提下调用某个函数或方法。 两者只有一个区别,call方法接受的是若干个参数的列表,参数之间以逗号分隔 而apply方法接受的是一个包含多个参数的数组或者伪数组(比如arguments)。
思考以下代码:
var objA = { x:"value is A", getX:function () { console.log(this.x); } }; var objB={ x:"value is B", getX:function () { console.log(this.x); } }; objA.getX(); //"value is A" objA.getX.call(objB);//"value is B",this被重新绑定到了objB上
上面的代码很简单,当objA.getX()被直接调用执行的时候,this理所应当地指向了objA对象,但是当objA.getX.call(objB)被调用执行时,objA.getX中的this被改变,指向了objB。此时因为没有其他参数要传入,所以本例中使用call和apply的输出结果是没有区别的。
他们区别在于传递参数的方式:
var objA = { x: "A", getX: function (val1, val2) { console.log(val1 + val2 + this.x); } }; var objB = { x: "B", getX: function (val1, val2) { console.log(val1 + val2 + this.x); } }; objA.getX.call(objB, "value", "is"); //"value is B" objA.getX.apply(objB, ["value","is"]); //"value is B"
PS:若想了解更多关于this关键词的知识,请阅读这篇文章
用作类的继承call与apply方法使用的一个最常见的场景就是在js类的继承中使用,废话不多说,直接上代码:
var Person = function (name, age) { this.name = name; this.age = age; this.sayAge = function () { console.log("Age:" + this.age); }; } var Worker = function (name, age, workerId) { this.workerId = workerId; Person.apply(this, arguments); //apply的第二个参数也可以是伪数组 this.showId = function () { console.log(this.workerId); } } var worker = new Worker("张三", 22, "521608"); worker.sayAge();
需要注意的一点是,使用call和apply方法不能继承原型链,如果要实现原型链继承,则需要混合使用子类原型对象指向父类的实例的方式实现继承。具体可参考下面代码
var Person = function (name,age) { this.name = name; this.age = age; this.sayAge = function () { console.log("Age:"+this.age); }; } //定义到原型链上的方法 Person.prototype.sayName = function () { console.log("Name:"+this.name); }; var Worker = function (name,age,workerId) { this.workerId= workerId; Person.apply(this,arguments);//这里没有继承父类prototype中的方法 } Worker.prototype = new Person(this.name,this.age); Worker.prototype.showId = function () { console.log("ID:",this.workerId); }; var worker = new Worker("张三",22,"521608"); worker.sayAge(); //"Age:22" worker.sayName();//"Name:张三" worker.showId();//"ID: 521608"太史公曰
总结一下call与apply
兄弟俩的任务:
使用一个指定的this值和若干个指定的参数值的前提下调用某个函数或方法。
区别:
call方法接受的是若干个参数的列表,参数之间以逗号分隔 而apply方法接受的是一个包含多个参数的数组或者伪数组(比如arguments)。
本篇人物小传自此结束。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/90971.html
摘要:系统,扎实的语言基础是一个优秀的前端工程师必须具备的。第一个参数为调用函数时的指向,随后的参数则作为函数的参数并调用,也就是。和的区别只有一个,就是它只有两个参数,而且第二个参数为调用函数时的参数构成的数组。 系统,扎实的 javascript 语言基础是一个优秀的前端工程师必须具备的。在看了一些关于 call,apply,bind 的文章后,我还是打算写下这篇总结,原因其实有好几个。...
摘要:前言实践系列主要是让我们通过实践去加深对一些原理的理解。求求三兄弟的作用都是为了改变函数运行时上下文指向而存在的。不会立即调用其他两个会立即调用。如果有帮助到你请给我一个就算是对我的感谢啦 前言 [实践系列] 主要是让我们通过实践去加深对一些原理的理解。 实践系列-前端路由 实践系列-Babel原理 实践系列-Promises/A+规范 实践系列-浏览器缓存机制 有兴...
摘要:出现箭头函数的时候,指向为定义时的上下文对象而非指向时,并且不能被改变首先我们先看一个例子由上面的例子我们可以看出来此时指针在用改变了之后指向的依然是全局对象非严格浏览器环境中是而非。 javascript基础之this指针 越往后面学越发现基础的重要性,所以打算重新过一遍基础,之后出几个vue和react的实战教程。ok,严归正传。 首先什么是this this是执行上下文创建时确定...
摘要:他们的布尔值都是,说到布尔值为的,通常包括空字符串这五种常见的对象。各自都是孤家寡人,不用拖家带口的,一人吃饱全家不饿。 举个简单的栗子: A和B两个人肚子都很饿,要去吃饭。A已打电话到饭店预约位置,B则打算下班后考察下再做决定。对于饭店来说,A基本上就是他的客户了,只不过还没见到人来,定为null(毕竟交易还没产生),而对饭店来说,B是谁啊,他们根本没听到过这个人,为undefine...
摘要:使用构造函数的原型继承相比使用原型的原型继承更加复杂,我们先看看使用原型的原型继承上面的代码很容易理解。相反的,使用构造函数的原型继承像下面这样当然,构造函数的方式更简单。 五天之前我写了一个关于ES6标准中Class的文章。在里面我介绍了如何用现有的Javascript来模拟类并且介绍了ES6中类的用法,其实它只是一个语法糖。感谢Om Shakar以及Javascript Room中...
阅读 2807·2021-11-25 09:43
阅读 959·2021-10-11 10:57
阅读 2462·2020-12-03 17:20
阅读 3695·2019-08-30 14:05
阅读 2391·2019-08-29 14:00
阅读 1976·2019-08-29 12:37
阅读 1637·2019-08-26 11:34
阅读 3181·2019-08-26 10:27