文章目录
一.函数的定义、调用、this指向问题
1.函数的三种定义
<script>
// 1.自定义函数(命名函数) function 关键字
function fun(){};
// 2.函数表达式(匿名函数)
var fun = function(){};
// 3.利用new Function('arg1','arg2',...,'函数体');
// 不推荐使用,效率较低
var f = new Function('id','name','console.log(123)');
f();
// 所有的函数都是对象,所有函数都是Function的实例对象
console.dir(f instanceof Object);//true
console.dir(Function.prototype.constructor);
</script>
2.函数的六种调用方式及函数内部的this指向
函数的不同调用方式决定了this的指向不同
<script>
// 1.普通函数 this 指向window
function fn() {
console.log('普通函数的this指向' + this);
// [object Window]
}
// fn(); fn.call()都可以调用
fn();
// 2.对象的方法 this 指向 方法的所属对象
var obj = {
sayHi: function () {
console.log('对象方法的this指向' + this);
//[object Object]
}
};
obj.sayHi();
// 3.构造函数 this 指向实例对象,原型对象中的方法也指向实例对象
function Star() { };
Star.prototype.sing = function(){};
var lgx = new Star();
// 4.绑定事件函数 ths 指向绑定事件对象
btn.onclick = function () { };//点击按钮就可以调用
// 5.定时器函数 this 指向window
setInterval(function () { }, 1000);
// 定时器自动调用
// 6.立即执行函数 this 指向window
(function () {
console.log('坚持就是胜利!');
})()
// 自动调用
</script>
3.改变函数内部this指向的三种方法
(1)call()方法
<script>
// 1.call()
var obj = function(){
name: 'lindsay'
}
function fn(a,b){
console.log(this);
console.log(a+b);
}
// 要实现this指向o这个对象而不是window
fn.call(obj,1,3);
// call可以调用函数,也可以改变函数内this的指向
// call主要作用实现继承
function Father(uname,age,sex){
this.unmae = uname;
this.age = age;
this.sex = sex;
}
function Son(uname,age,sex){
// 调用父亲,这里的this指向的是儿子
Father.call(this,uname,age,sex);
}
var lgx = new Son('林更新',19,'male');
console.log(lgx);
</script>
(2)apply()方法
<script>
var obj = function(){
name: 'lindsay'
}
function fn(arr){
console.log(this);
console.log(arr);//打印的不是数组是一个字符串
}
// 1.apply可以调用函数,也可以改变this的指向
// 2.参数必须是数组形式(伪数组)
fn.apply(obj,['lindsay']);
// apply的主要应用
// 利用apply借助于数学内置对象求最值
var arr = [1,55,34,90];
// 这里用Math或者this都可以,指向都是window
var max = Math.max.apply(this,arr);
var min = Math.min.apply(Math,arr);
console.log(max,min);
</script>
(3)bind()方法
<button>点击</button>
<script>
// 1.不会调用函数但是可以该笔那this的指向
var obj = function(){
name: 'lindsay'
}
function fn(a,b){
console.log(this);
console.log(a+b);
}
fn.bind(obj);//并没有输出,说明没有调用fn这个函数,只是绑定了
// 2.返回的是原函数改变this之后产生的新函数
var f = fn.bind(obj,1,2);//f是一个函数
f();
// 3.如果有的函数不需要立即调用,但是想改变函数内部的This指向此时就用bind
// 举例:有一个按钮,当点击了之后就禁用这个按钮,3秒钟之后再开启这个按钮
var btn = document.querySelector('button');
btn.addEventListener('click',function(){
this.disabled = true;//这里的this指向的是btn
// var that = this;
setTimeout(function(){
// that.disabled = false; 方法一
// btn.disabled = false 方法二,但是btn可能有很多个比较麻烦
this.disabled = false; // setTimeout指向的是window,改变它的指向为btn
}.bind(this),3000) //原本是bind(btn),这里的btn就是this
})
</script>