ECMAScript规范中,所有函数都包含这两个方法,并且两个方法的使用基本一致,都是用于改变函数的作用域,即改变函数体内 this 指向。不同的是 call 方法的第二个参数可以接收任意个参数,以逗号分隔;而 apply 方法的第二个参数必须是一个数组或者类数组。
1、改变 this 指向
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <script type="text/javascript"> var name = "Java"; var obj = {name: "Javascript"}; function sayName() { return this.name; } console.log(sayName.call(window)); // 输出"Java",将this指向window console.log(sayName.call(obj)); // 输出"Javascript",将this指向obj console.log(sayName.apply(window)); // 输出"Java",将this指向window console.log(sayName.apply(obj)); // 输出"Javascript",将this指向obj </script> </body> </html>
2、调用函数
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <script type="text/javascript"> function add(x, y) { return x + y; } function myAddCall(x, y) { return add.call(this, x, y); } function myAddApply(x, y) { return add.apply(this, [x, y]); } console.log(myAddCall(10, 20)); // 输出结果30 console.log(myAddApply(20, 20)); // 输出结果40 </script> </body> </html>
3、实现继承
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <script type="text/javascript"> // 父类 Person function Person() { this.sayName = function() { return this.name; } } // 子类 Chinese function Chinese(name) { // 借助 call 实现继承 Person.call(this); this.name = name; } // 子类America function America(name) { // 借助 call 实现继承 Person.call(this); this.name = name; } var chinese = new Chinese("你好"); //调用 父类方法 console.log(chinese.sayName()); // 输出 "你好" var america = new America("Hello"); // 调用 父类方法 console.log(america.sayName()); // 输出 "Hello" </script> </body> </html>