函数的定义方式
自定义函数(命名函数)
function fun() {}
函数表达式(匿名函数)
let fun = function() {};
使用
new Function('arg1', 'arg2', ... , '函数体')
let fun = new Function('x', 'y', 'console.log(x + y)'); // 参数都是字符串形式 fun(1, 2) // 输出 3
所有函数都是Function的实例(对象),函数也是对象,也有原型
fun instanceof Object; // true
fun.__proto__.constructor === Function; // true
函数的调用与this指向
普通函数
function fun() { console.log(this); // this指向window } fun(); // == window.fun()
对象的方法
let wuzi = { say: function() { console.log(this); // this指向对象 } } wuzi.say();
构造函数
// 构造函数以及构造函数的原型对象中的this指向实例对象 function People() {}; let wuzi = new People();
绑定事件函数
btn.onclick = function() { console.log(this); // 指向函数的调用者,即btn }; // 点击触发
定时器函数
setInterval(function() { console.log(this); // 指向window }, 1000); // 每隔一段时间调用一次
立即执行函数
// 自动调用 (function() { console.log(this); // 指向window })();
改变函数内部的this指向
call
let wuzi { name: 'uzi' } function fun(a,b) { console.log(this); // wuzi console.log(a + b); // 3 }; fun.call(wuzi, 1, 2); // call调用函数,第一个参数改变函数内部this的指向,后面为函数的参数
可以使用call实现继承功能
function Father(name, age) { // this 指向父构造函数的对象实例 this.name = name; this.age = age; } function Son(name, age, sex) { // this 指向子构造函数的对象实例 Father.call(this, name, age); this.sex = sex; }
apply
let wuzi { name: 'uzi' } function fun(a,b) { console.log(this); // wuzi console.log(a + b); // 3 }; fun.apply(wuzi, [1, 2]); // apply调用函数,第一个参数改变函数内部this的指向,参数必须以数组的形式传递
应用
let arr = [1, 2, 5, 3, 4]; let max = Math.max.apply(null, arr); // 利用数学内置对象求最大值 // == Math.max.apply(Math, arr); // == let max = Max.max(...arr); // 使用解构
bind
let wuzi { name: 'uzi' } function fun(a,b) { console.log(this); // wuzi console.log(a + b); // 3 }; let newFun = fun.bind(wuzi, 1, 2); // 不会调用函数,返回改造完this后产生的新函数的拷贝 newFun(); // 调用
如果有的函数不需要立即调用,想要改变函数内部this指向,则应该使用bind
// 点击按钮后禁用按钮,3秒后恢复 let btn = document.querySelector('button'); btn.onclick = function() { this.disabled = true; // this指向btn setTimeout(function(){ this.disabled = false; // 绑定了btn, 否则this指向window }.bind(this), 3000) }
相同点与区别
相同点:都可以改变函数内部的指向
区别:
- call和apply会立即调用函数,bind不会调用
- call和bind传递参数以逗号分隔,apply必须以将参数放在一个数组中
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!