JS函数的4种调用模式
若有不妥,请多指教
<a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/apply">学习网址推荐</a>
JS函数的4种调用模式包括:
1.函数模式
2.方法模式
3.构造函数模式
4.上下文模式(也有叫apply模式)
1.函数模式
就是最基本的函数
function test1() {
//this指向window全局对象
console.log(this);
}
test1();
2.方法模式
我们创建一个对象,这个对象有一个函数,那这个函数就叫方法,通过对象调用方法的模式
var obj2 = {
test2:function () {
//this指向调用这个方法的对象
console.log(this);
}
}
obj2.test2();
3.构造函数模式
构造函数的注意事项:
1>首字母要大写
2>构造函数中的this指定的是创建出来的对象
3>函数默认返回的是创建出来的对象
3.1构造模式:
function Star(name,age) {
this.name = name;
this.age = age;
this.sayHello = function () {
//this指向使用new创建出来的对象
console.log(this.name + 'hi');
}
}
var star = new Star("邱淑贞",18);
star.sayHello();
3.2工厂模式:
工厂就是用来模式化生产东西的, 因此如果函数创建对象并返回, 就称该函数为工厂函数
function Star(name,age) {
var obj = {
name:name,
age:age,
sayHello:function () {
console.log(this.name + 'hi');
}
}
return obj;
}
var star = Star("邱淑贞",18);
star.sayHello();
或者这种写法
function Star(name,age) {
var obj = new Object();
obj.name = name;
obj.age = age;
obj.sayHello = function () {
console.log(this.name + 'hi');
}
return obj;
}
var star = Star("邱淑贞",18);
star.sayHello();
3.3寄生式构造函数模式:
提到工厂模式就不得不提寄生式构造函数
可以看出二者的不同就是调用时一个用new,一个没有用new
function Star(name,age) {
var obj = {
}
obj.name = name;
obj.age = age;
obj.sayHello = function () {
console.log(this.name + 'hi');
}
return obj;
}
var star = new Star("邱淑贞",18);
star.sayHello();
作用嘛寄生构造函数专门用来为js原生的构造函数扩展新的方法
假设我们想创建一个具有额外方法的特殊数组
由于不能直接修改Array构造函数,所以我们可以使用寄生模式
function SpecialArray() {
//创建数组
var array=new Array();
//添加值 arguments获取的是实参,不是形参,所以SpecialArray()并没有形参接收传递过来的参数
array.push.apply(array,arguments);
array.toPipedString=function(){
return this.join("|");
}
return array;
}
var colors=new SpecialArray("red","blue","black");
alert(colors.toPipedString()); //输出:red|blue|black
4.上下文模式
可以看出,前面三种函数调用模式的最主要区别就是this的指向不同
而上下文模式最主要的功能就是可以修改this的指向,指定的谁就是谁
实现方式为:
1>函数.call(对象,参数1,参数2,参数3,参数4)
2>函数.apply(对象,数组)
二者都可以用来改变this的指向为参数的第一个值(对象)
第一个参数:
如果传入的是一个对象, 那么就相当于设置该函数中的 this 为参数
如果不传入参数, 或传入 null undefiend 等, 那么相当于 this 默认为 window
第二个参数:
在使用此模式调用的时候, 原函数(方法)可能会带有参数, 那么这个参数使用第二个( 第 n 个 )参数来表示
call在函数的形参个数确定的情况下使用
apply在函数的形参个数不确定的情况下使用
如果是函数调用test(), 那么有点类似于test.apply(window)
如果是方法调用obj.method(), 那么有点类似于obj.method.apply(obj)
看一个简单的例子:
运行结果是打印两次"邱淑贞漂亮等级为:100级"
而不是王祖贤
var name = "王祖贤";
function sayHello(a,b) {
console.log(this.name + '漂亮等级为:' + (a * b) + '级');
}
var obj = {
name:"邱淑贞"
}
sayHello.apply(obj,[10,10]);
sayHello.call(obj,10,10);
再看一个快速打印数组中最大值的例子:
运行结果是打印66
var arr = [9,12,23,22,11,33,66];
var max = Math.max.apply(null,arr);
console.log(max);
再看一个将所有参数用-连接起来的例子:
运行结果为打印
0: "66-王祖贤-邱淑贞-覃芳菲-都是大美女-66"
1: "66+王祖贤+邱淑贞+覃芳菲+都是大美女+66"
function test() {
//arguments是所有形参的集合
//在函数中,使用特殊对象arguments,无需明确指出参数名,就能访问它们
var str1 = Array.prototype.join.apply(arguments,["-"]);
var str2 = Array.prototype.join.call(arguments,"+");
var arr = [str1,str2];
return arr;
}
var arr = test(66,"王祖贤","邱淑贞","覃芳菲","都是大美女",66);
console.log(arr);
值得注意的是:
当用call和apply传入的第一个参数为值类型的时候,会将值类型转换成对应的对象(引用类型)然后赋值给this
当传入的第一个参数为 null或者undefined的时候,会把this赋值为window
function test() {
console.log(this);
}
test.apply(1); //打印Number
test.apply("abc"); //打印String
test.apply(true); //打印Boolean
test.apply(undefined); //打印Window
test.apply(null); //打印Window
4.1借用构造函数实现继承:
运行结果为打印Star {name: "邱淑贞", age: 18}
function Person(){
this.name = "邱淑贞";
this.age = 18;
}
function Star(){
var star = this;
Person.apply(star);
}
var star = new Star();
console.log(star);