javascript call和apply用法

1 篇文章 0 订阅
1 篇文章 0 订阅

参考:https://segmentfault.com/a/1190000009556703#articleHeader3

在ES6中,箭头函数this指向定义时的对象,省去了var that=this的麻烦,耶耶耶~~~

接下来我们来总结一下,在ES5中:

this的值通常是由当前函数的执行环境所决定;

在全局作用域,this指向全局对象 (window对象);

当使用new关键字声明,this指向新建对象;

我们可以使用call(), bind(), apply()来设置this;

箭头函数不会绑定this
这里写图片描述

bind的模拟实现
bind 函数的两个特点:
1. 返回一个函数
2. 可以传入参数

Function.prototype.bind2 = function(context){
    var that = this;
    return function (){
        that.apply(context)
    }
}
var foo = {value:1}
var f = function(){
    console.log(this.value)
}
f.bind2(foo)();//1

call的模拟实现
1. 将函数设为对象的属性
2. 执行该函数
3. 删除该函数
参考:https://blog.csdn.net/daimomo000/article/details/72897008

对比:

非箭头函数:

function fo() {
setTimeout(function() {
console.log(‘id:’, this.id);
}, 100);
}
var id = 21;
fo.call({ id: 42 });
// id: 21

箭头函数:

function foo() {
setTimeout(() => {
console.log(‘id:’, this.id);
}, 100);
}
var id = 21;
foo.call({ id: 42 });

// id: 42

上面代码中,setTimeout的参数是一个箭头函数,这个箭头函数的定义生效是在foo函数生成时,而它的真正执行要等到 100 毫秒后。如果是普通函数,执行时this应该指向全局对象window,这时应该输出21。但是,箭头函数导致this总是指向函数定义生效时所在的对象(本例是{id: 42}),所以输出的是42。

箭头函数可以让setTimeout里面的this,绑定定义时所在的作用域,而不是指向运行时所在的作用域。

上代码

<script type="text/javascript">
 //定义一个人类
function Person(name,age){
    this.name=name;
    this.age=age
}
//定义一个学生
function Student(name,age,grade){
    Person.apply(this,arguments)//定义时,this指Student, arguments打出来是["Li", 11, "一班", callee: ƒ, Symbol(Symbol.iterator): ƒ]
    this.grade=grade
}
var s=new Student("Li",11,"一班")
console.log(s);//{name: "Li", age: 11, grade: "一班"}

</script>
分析

Person.apply(this,arguments)等同于
Person.call(this,name,age)

如果说Person和Student的参数顺序不一样,必须用call了

<script type="text/javascript">
 //定义一个人类
function Person(n,a){
    this.n=n;
    this.a=a
}
//定义一个学生
function Student(age,name,grade){
    Person.call(this,age,name)
    console.log("1",this)//1 Student {n: "Li", a: 11}
    this.grade=grade
}
var s=new Student("Li",11,"一班")
console.log(s);//Student {n: "Li", a: 11, grade: "一班"}

</script>
应用:

1.apply可以将数组转化为一个参数接一个参数
Math.max(param1,param2,param3…)

Math.max(1,3,5,2)
//5

数组的话

Math.max([1,3,5,2])
//NaNMath.max.apply(null,[1,3,5,2])
5

上面是ES5的写法
ES6的话,直接用扩展运算符…,将数据组转化为参数序列:

Math.max(...[1,3,5,2])
//5
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值