函数的定义和调用
函数的定义方式
- 自定义函数 (命名函数)
function fn() {};
- 函数表达式 (匿名函数)
var fun = function() {};
- 利用 new Function(‘参数1’,‘参数2’,‘函数体’)
var f = new Function('a', 'b', 'console.log(a+b)');
f(1, 2);
(1) Function里面参数都必须是字符串
(2) 这种方法执行效率低,也不方便书写,较少使用
(3) 所有函数都是Function的实例(对象)
函数的调用方式
函数的不同调用方式决定了this的指向不同
- 普通函数 ( this指向 window)
function fn() {
console.log("函数");
}
fn();
fn.call()
- 对象的方法( this指向的是对象o(即调用者))
var o = {
SayHi: function() {
console.log("函数");
}
}
o.SayHi();
- 构造函数 ( this指向的是实例对象(ldh) ,原型对象里面的this指向的也是ldh这个实例对象)
function Star() {};
Star.prototype.sing = function(){ };
var ldh = new Star();
- 绑定事件函数 ( this指向绑定事件对象(btn这个按钮对象) )
btn.onclick = function() {}; //点击按钮可以调用
- 定时器函数 ( this指向window)
setInterval(function() {}, 1000); //定时器每隔一秒调用一次
- 立即执行函数 不需要调用,会自动执行 ( this指向window)
(function() {
console.log("函数");
})();
改变函数内部this指向
- call()可以调用函数,也可以改变函数的this指向,主要作用是用来实现继承
fun.call(thisArg,arg1,arg2,....)
//1.call()方法
var o = {
name:'andy'
}
function fn(){
console.log(this); //此时this指向window
}
fn.call(o);//将this指向改为指向o
function Father(uname,age,sex){
this.uname = uname;
this.age = age;
this.sex = sex;
}
function Son(uname,age,sex){
Father.call(this,uname,age,sex);
//调用父构造函数的同时,把父构造函数的this改成指向子构造函数
}
- apply()方法
可以调用函数,也可以改变函数的this指向
fun.apply(thisArg,[argsArray])
thisArg:在fun运行时指定的this值
argsArray:传递的值,必须包含在数组里面
(1)返回值就是函数的返回值,因为它就是调用函数
(2)参数必须是数组(伪数组)
(3)apply主要应用于数组 比如可以利用apply借助于数学内置对象求数组最大值
//2.apply()
var o = {
name: 'andy'
}
function fn(arr) {
console.log(arr); //'pink'
}
fn.apply(o, ['pink']);
//利用apply借助于数学内置对象求数组最大值
var arr = [1, 66, 2, 99, 4];
var max = Math.max.apply(Math, arr);
console.log(max);
- bind()方法
此方法不会调用函数,但能改变函数内部this指向
fun.bind(thisArg,arg1,arg2,....)
thisArg:在fun运行时指定的this值
arg1,arg2:传递的其他参数
返回由指定的this值和初始化参数改造的原函数拷贝
//bind()方法
var o = {
name: 'andy'
}
function fn() {
console.log(this);
}
var f = fn.bind(o);
f();//this指向o
//bind的应用: 有一排按钮,点击之后就禁用这个按钮,3s之后再开启
var btns = document.querySelectorAll('button');
for (var i = 0; i < btns.length; i++) {
btns[i].onclick = function() {
this.disabled = true;
setInterval(function() {
//定时器里面的this指向的是window,因此不可以直接用 this.disabled = false;
this.disabled = false;
}.bind(this), 3000)
}
}
apply,call,bind总结:
相同点:都可以改变函数内部的this指向
区别点:
- call 和 apply 会调用函数,并且改变函数内部this指向
- call 和 apply 传递的参数不一样,call传递参数aru1,aru2…(以逗号分割)形式,apply必须数组形式
- bind 不会调用函数,可以改变函数内部this指向
call主要做继承,apply做跟数组有关系的,bind用于不调用函数而改变指向问题的情况(比如定时器)