函数定义方式
- 所有函数都Function的实例对象。
- 函数也属于对象
- 指向:表示这个函数是谁的属性。调用函数得人是谁。函数指向window就是,window调用这个函数。
三种方式
<script>
//1.自定义函数
function f(){};
//2.函数表达式(匿名函数)
var fun=function(){};
//3.利用new Function('参数1','参数2',函数体);
//执行效率低
var f=new Function('a','b','console.log(a+b)');
f(1,2);
</script>
函数的调用
<script>
//1.普通函数
function f(){
console.log('人生巅峰');
}
fn.call(); fn();
//2.对象的方法
var o{
say:function();{
console.log('人生巅峰');
}
}
o.say();
//3.构造函数
function Star(){};
new Star();
//4.绑定事件函数
btn.onclick=function(){};
//5.定时器函数
setInterval(function(){},1000);//定时器一秒钟调用一次。
//6.立即执行函数
(function(){
console.log('人生巅峰');
})();
//立即执行,自动调用。
</script>
不同函数的this指向问题
- 指向:表示这个函数是谁的属性。调用函数得人是谁。
- 如window调用this,那么就是this指向window。
<script>
//1.普通函数this指向window
function f(){
console.log('人生巅峰');
}
window.fn();
//2.对象的方法this指向o
var o{
say:function();{
console.log('人生巅峰');
}
}
o.say();
//3.构造函数this指向ldh这个实例对象
//原型对象里的this指向的也是ldh对象实例
function Star(){};
new Star();
Star.prototype.sing(){}
var ldh=new Star();
//4.绑定事件函数。this指向函数调用者,也就是btn
btn.onclick=function(){};
//5.定时器函数。this指向window。
//函数调用者是window
setInterval(function(){},1000);
//6.立即执行函数
//指向的是window
(function(){
console.log('人生巅峰');
})();
//立即执行,自动调用。
</script>
可以改变函数内部this指向不同对象
call()
- call是一个可以调用函数 第二个可以改变函数内this指向
- call主要作用可以实现继承
<script>
//1.call()
var o={
name:'andy'
}
function f(){
console.log(this);
};
//由window改成0
f.call(o);
//2.实现继承
function father(name,age){
this.name=name;
this.age=age;
}
function son(name,age){
//改变指向
//调用父类构造方法,传递儿子的值。
father.call(this,name,age);
}
var son=new son('lll',19);
</script>
apply
apply()方法调用一个函数。简单理解为调用函数方式,但是他可以改变this指向。
fun.apply(thisArg,[argsArray])
- thisArg:在fun函数运行时指定this的值。
- argsArray:传递的值,必须包含在数组里面
- 返回值就是函数的返回值,因为它就是调用函数
<script>
//2.apply()
var o={
name:'andy'
}
function f(){
console.log(this);
//打印的不是数组形式,是字符串形式。
console.log(arr);
};
//1.调用函数,改变函数内部this指向
//2.必须是数组形式
//3.apply主要作用 用apply借助于数学内置对象最大值。
//Math.max();
var arr=[1,66,3,99,4];
var max=Math.max.apply(null,arr);
//尽量不用null。理解为自己调用自己
var max=Math.max.apply(Math,arr);
f.apply(o,['pink']);
</script>`在这里插入代码片`
bind
类似于绑定到某一新函数身上,不会调用原函数。
bind()方法不会调用函数,但是能改变函数内部this指向。
fun.bind(this.Arg,arg1,arg2,…)
- thisArg:在函数运行时指定的this值。
- arg1,arg2:传递的其他参数
- 返回由指定的this值和初始化参数改造的原函数的拷贝
我们有一个按钮,当我们点击之后,就禁用这个按钮,3秒钟之后开启这个按钮。
- 时间函数指向的btn按钮。定时器函数this指向的是window
- bind里this指向btn这个对象,因为在function括号外面
- 定时器不需要立刻执行,但又需要this指向btn
<body>
<button>点击</button>
<script>
//3.bind()
var o={
name:'andy'
}
function f(a,b){
console.log(this);
console.log(a+b);
};
//只是绑定,并不执行
var f2=f.bind(o,1,2);
f2();
//1.不会调用原来函数 可以改变原来函数内部this指向
//2.返回的是原函数改变this之后的新函数
//3.我们有一个按钮,当我们点击之后,就禁用这个按钮,3秒钟之后开启这个按钮。
var btn=document.querySelector('button');
btn.onclick=function(){
this.disabled=true;//时间函数指向的btn按钮
var that=this;
setTimeout(function(){
that.disabled=false;//定时器函数this指向的是window
},3000)
}
//====================================================================
var btn=document.querySelector('button');
btn.onclick=function(){
this.disabled=true;//时间函数指向的btn按钮
setTimeout(function(){
this.disabled=false;//定时器函数this指向的是window
}.bind(this),3000)
}//bind里this指向btn这个对象,因为在function括号外面
//定时器不需要立刻执行,但又需要this指向btn
</script>
</body>
适用于:有的函数不需要立刻调用,但是又想改变内部的this指向。
总结
相同点:
- 都可以改变函数内部this指向
不同点:
- call和apply都会调用函数,并且改变内部this指向
- call和apply传递的函数不一样,call传递参数arg1,arg2形式。apply必须数组形式[arg]
- bind不会立刻调用函数,可以改变函数内部this指向
主要应用场景:
- call经常做继承
- apply经常跟数组有关系,比如借助数组求最大值最小值
- bind不调用函数,但是想改变this指向,比如定时器this指向。