您的位置:首页 > 移动开发

JavaScript中this、apply()、call()的用法及解释示例

2017-08-08 20:40 831 查看
说到javascript中的this不得不提及javascript中函数调用的四种模式,即

函数调用模式

对象的方法调用模式

构造函数调用模式

上下文调用模式

因为不同的函数调用模式,this的指向时不同的。现在一一来看四种调用模式。

1.函数调用模式:

function test(){
console.log(this);//window
}
test();


这也是函数最通常的用法,属于全局性调用。*因此this指向window*

2.对象的方法调用模式

var age = 10;
var obj = {
age : 20,
test:function(){
console.log(this.age); //20
}
}
obj.test();


将函数作为对象的属性,这样就转化为对象的一个方法。通过对象调用这个方法时,this就指向调用这个方法的对象。

3.构造函数模式

function Person(age){
this.age = age;
this.sayAge = function() {
console.log(this.age);
}
}
var obj =new Person(18);
obj.sayAge();
var obj1 = new Person(20);
obj1.sayAge(); //20


.构造函数中的this指定的是new关键字创建出来的对象。

4.上下文调用模式

在讲这个之前,练习几道题目算是对函数调用模式,对象方法调用模式,构造函数模式的巩固。

讲道理,你知道下面分别输出什么吗?

var age = 10;
var obj = {
age : 18,
getAge : function(){
console.log(this.age);
}
};
var a = obj.getAge();
var getAge = obj.getAge;
getAge();




var age = 10;
var obj = {
age :18,
getAge : function(){
console.log(this.age);
function foo(){
console.log(this.age);
}
foo();
}
};
obj.getAge();




来个简单的吧

var age = 38;
var obj = {
age:18,
getAge: function() {
console.log(this.age);
}
};
var f = obj.getAge;
f();




来个难一点的

var length = 99;
function f(){
console.log(this.length);
}
var obj = {
length : 5,
method : function(f) {
f();
arguments[0]();
}
};
obj.method(f,1,2,3,4,5);
arguments是一个伪数组对象. 它表示在函数调用的过程中传入的所有参数的集合。在函数调用过程中不规定参数的个数与类型, 可以使得函数调用变得非常灵活性。
先来个截图看看arguments中存储的是什么吧!




Arguments[0]相当于f函数,Arguments[0]()相当于调用f函数。




好了,接下来看第4中模式,上下文模式

4上下文模式

在JavaScript中,所有的函数都是对象,因此函数也可以有自己的方法。所有的函数都有的两个方法,是apply(),call()。通过这两个方法可以修改this的值,也就是可以修改函数的调用方式。

apply()方法调用给一个函数,其具有一个指定的this值,以及作为一个数组(或类似数组的对象)提供的参数

函数.apply(对象,函数需要的参数列表是一个数组)

fun.apply(thisArg,[argsArray])

参数

thisArg: 在fun函数运行时指定的this值。 需注意:指定的this值并不一定是该函数执行时真正的this值,如果这个函数处于非严格模式下,则指定为null或undefined时会自动指向全局对象(浏览器中的window对象),同时值为原始值(数字,字符串,布尔值)的this会指向该原始值的自动包装对象。

argsArray 一个数组或者类数组对象,其中的数组元素将作为单独的参数传给fun函数。如果该参数的值为null或undefined,则表示不需要传入任何参数。

call()方法的作用和apply()方法类似。区别是,call()方法接受的是若干个参数列表,而apply()方法接受的是一个包含多个参数的数组。

函数.call(对象,arg1,arg2,arg3…argn)

fun.call(thisArg,arg1,arg2,…)

简单总结一下

1.第一个参数都是要把this修改成的对象

2.当函数需要参数的时候,那么apply是用数组进行参数的传递

3.而call是使用单个的参数进行传递。

4.apply用于确定了函数形参有多少个的时候使用,apply用于函数的形参个数不确定的情况

示例1:

var nickname = "kong";
function sayNick(){
console.log(this.nickname);
}

var obj = {
nickname: "diligentkong"
}

sayNick.apply(obj); //diligentkong
sayNick.call(obj);//diligentkong

var obj1 = {
nickname :"qq"
}
sayNick.apply(obj1);//qq
sayNick.apply(null);//kong
sayNick.apply(undefined);//kong
sayNick.apply(window);//kong


function test(){
console.log(this);
}
test.apply(1); //Numner
test.apply("a"); //String
test.apply(true); //Boolean

// 如果想取值的话,把test()修改为
function test(){
console.log(this.valueOf());

}
test.apply(1); //1
test.apply("a"); //a
test.apply(true); //true


apply()的妙用,求一个数组中的最大值
var arr =[3,10,2,7,-4,56,88];
var Arrmax = Math.max.apply(null,arr);
console.log(Arrmax); //88


解释一下:

apply()和call()方法第一个参数为null时2,都表示为函数调用模式,也就是this指向window

apply()方法的第二个参数是一个数组,再调用的时候,会把数组中的每一个元素拿出来,挨个传递个函数

将传入的参数打印,参数之间用-相互连接
function fun(){
//var str = Array.prototype.join.apply(arguments,["-"]);
var str = [].join.apply(arguments,["-"]);
return str;
}
var str =fun("a","t",9,"c",6);
console.log(str);


还可以用apply和call 实现继承,这种继承的方法叫 借用构造函数

function Person() {
this.name ="kong";
this.age = 18;
}
function Student() {
Person.apply(this);
}
var stu = new Student();

console.log(stu);




内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  this call apply