call()方法的作用和 apply() 方法类似,区别就是call()方法接受的是参数列表,而apply()方法接受的是一个参数数组。
本文参照:js中继承的几种用法总结(apply,call,prototype) 原文链接
js原型(prototype)实现继承
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHello = function () {
console.log("使用原型得到Name:" + this.name);
}
const per = new Person("马小倩", 21);
per.sayHello();
function Student() {}
Student.prototype = new Person("红如同", 21);
var stu = new Student();
Student.prototype.grade = 5;
Student.prototype.intr = function(){
console.log(this.grade)
}
stu.sayHello();
stu.intr();
// 输出
// 使用原型得到Name:马小倩
// 使用原型得到Name:红如同
// 5
构造函数实现继承
function Parent(name) {
this.name = name;
this.sayParent = function () {
console.log("parent:", this.name)
}
}
function Child(name, age) {
this.tempMethod = Parent;
this.tempMethod(name);
this.age = age;
this.sayChild = function () {
console.log(`child:${this.name} Age:${this.age}`);
}
}
var parent = new Parent("爸爸的名字");
parent.sayParent();
var child = new Child("李明", 24);
child.sayChild();
// parent: 爸爸的名字
// child:李明 Age:24
call、apply实现继承
function Person(name, age, love) {
this.name = name;
this.age = age;
this.love = love;
this.say = function () {
console.log("姓名:" + name);
}
}
// call方式
function Student(name, age) {
Person.call(this, name, age);
}
// apply方式
function Teacher(name,love){
Person.apply(this,[name,love]);
}
// call 与 aplly 的异同:
// 1,第一个参数this都一样,指当前对象
// 2,第二个参数不一样:call的是一个个的参数列表;apply的是一个数组(arguments也可以)
var per = new Person("五凤楼",25,"小满");
per.say();
var stu = new Student("曹宇",18);
stu.say();
var tea = new Teacher("谦老师","刚哥")
tea.say();
// 输出:
// 姓名:五凤楼
// 姓名:曹宇
// 姓名:谦老师
用 apply 实现的继承
function Person(name, age) {
this.name = name;
this.age = age;
this.sayhello = function () {
console.log("姓名:" + name);
}
}
function Print() {
this.funcName = "Print"
this.show = function () {
var msg = [];
for (var key in this) {
var item = this[key];
if (typeof (item) != 'function') {
// 将非函数的属性全部拼接到字符串输出
msg.push([key, ":", this[key]].join(""));
}
}
console.log("msg.join==>", msg.join(" "));
}
}
function Student(name, age, grade, school) {
/** 这里的 name、age、grade、school 参数,Person只用了一个apply,就都传递给 Person的前两个参数了 */
Person.apply(this, arguments); //比call优越的地方,将参数全部丢给Person了,不用一个个来.
Print.apply(this, arguments);
this.grade = grade;
this.school = school;
}
var p1 = new Person("不开花", 80);
p1.sayhello();
var s1 = new Student("白云飞", 40, 9, "国立新屋熊大学");
s1.show();
s1.sayhello();
console.log("s1.funcName", s1.funcName);
// 姓名:不开花
// msg.join==> name:白云飞 age:40 funcName:Print grade:9 school:国立新屋熊大学
// 姓名:白云飞
// s1.funcName Print
用 apply 完成其他实际任务
// EXAMPLE 1
// 演示一个max方法及调用js自带max方法
function getMax(arr) {
var arrLen = arr.length;
for (var i = 0, ret = arr[0]; i < arrLen; i++) {
ret = Math.max(ret, arr[i]);
}
return ret;
}
function getMax2(arr) {
return Math.max.apply(null, arr);
}
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
const r1 = getMax(arr);
const r2 = getMax2(arr);
console.log(r1) // 9
console.log(r2) // 9 结果一样,你看代码差多少。
// EXAMPLE2
// 演示将arr2全部追加到arr1中,改变arr1的值和不改变arr1的值。
function c_concat(arr1, arr2) {
return arr1.concat(arr2);
}
function c_apply(arr1, arr2) {
return Array.prototype.push.apply(arr1, arr2);
}
const arr1 = ['a', 'b', 'c', 'd']
const arr2 = ['e', 'f', 'g']
// 不改变arr1的值
const r1 = c_concat(arr1, arr2);
console.log("RR1", r1); // (7) ["a", "b", "c", "d", "e", "f", "g"]
console.log("ARR1", arr1); // (4) ["a", "b", "c", "d"]
console.log("ARR2", arr2); // (3) ["e", "f", "g"]
// 改变了arr1的值,方法返回的是结果数组的长度
const r2 = c_apply(arr1, arr2);
console.log("RR2", r2); // 7
console.log("ARR1", arr1); // (7) ["a", "b", "c", "d", "e", "f", "g"]
console.log("ARR2", arr2); // (3) ["e", "f", "g"]