一说到call,
————总是**call
**、‘张三’、‘李四’的区别什么什么的,说的很清楚,转身还是傻傻分不清楚他们的区别了,相似的事情总是喜欢一起来说,这对于新手来说总是容易混乱的,今天就来理解下call的用法;
通俗点:
**
call
**的作用就是: 改变函数执行时的上下文 也就是this
的指向;
用法:
Food.call(thisArg, arg1, arg2, ...)
复制代码
来看个例子 --- A
function fun(){
this.name = 'fun-name'
this.age = 'fun-age'
}
var wrap = {
age: 'default',
name: 'default',
myfun: function() {
fun()
}
}
wrap.myfun();
console.log(wrap.age) // 'default'
console.log(window.age) // 'fun-age'
复制代码
直接运行这个函数 wrap.myfun();
执行这个函数后 1、在wrap
下面执行myfun()
后,其中的this
指向wrap
的,但是fun作为一个普通函数调用,其中的this
就是指向全局的 2、在window
全局下面创建了一个 age
属性,值为 'fun-age'
3、wrap
中的age
还是default
来看个例子 --- B
function fun(){
this.name = 'fun-name'
this.age = 'fun-age'
}
var wrap = {
age: 'default',
name: 'default',
obj: function() {
console.log(this === wrap) // true
fun.call(this) // **---注意这里打 call 了---**
}
}
wrap.myfun();
console.log(wrap.age) // 'fun-age' --发生了变化---
console.log(window.age) // 'age is not defined' --发生了变化---
复制代码
例子B运行时:
wrap.obj()
执行后,在执行fun
时,把this
, call进去了, 这个this
是指向wrap
,所以fun
执行时其中的this
指向的是wrap
,自然改变的就是wrap
中的age
,这就是call
的作用改变了fun
执行时的上下文;
好累,反正我是大概懂了他(this)刚才干了什么;
那么在我们的coding中,一般什么时候用到call了?
1、利用call来 做继承
var Person = function () {
this.fun = function() {
console.log('longlee') }
};
var student = function () {
Person.call(this);
};
var st = new student ();
st.fun() // 输出: longlee
复制代码
如果不在student函数中执行 call,new出来的实例是没有fun属性方法的;打call就可以实现继承Person方法了;
2、判断数据的类型 【object、 array、 null】
var obj1 = {name: 'longlee'}
var obj2 = ['longlee']
var obj3 = null
Object.prototype.toString.call(obj1) // "[object Object]"
Object.prototype.toString.call(obj2) // "[object Array]"
Object.prototype.toString.call(obj3) // "[object Null]"
Object.prototype.toString.call(12) // "[object Number]"
....
....
复制代码
3、类(伪)数组使用数组方法
var arg = Array.prototype.slice.call(arguments);
arguments是函数接收的实际参数个数,他是一个伪数组,不具有数组的一般方法。比如 push、pop...,
但是我们能通过 Array.prototype.slice.call 转换为真正的数组
这样 arguments 就可以应用 Array 下的所有方法了。
复制代码
4、获取数组中的最大值和最小值
maxInNumbers = Math.max.call(Math, 55, 888 , 521 , -36); // 888
number 本身没有 max 方法,但是 Math 有,我们就可以借助 call 使用其方法。
复制代码
就说到这了,再说下去,我自己也快消化不良了、、、、
题外话: 说到数组的最大值、最小值。我控制不住自己了,一个ES6的简洁方法 Math.max(...[2,1,3])
// 3 Math.min(...[2,1,3])
// 1
个人见解,有误之处,大神请指出,以免改正! 弄懂 call 了。可以继续打 call 了
function add() {
alert(123)
}复制代码