1.函數的定義和調用
1.1函數的定義方式
1.函數聲明方式function關鍵字(命名函數)
2.函數表達式(匿名函數)
3.new Function()
注意:(1)Function()裏面參數必須是字符串格式;(2)第三種方式執行效率低,也不方便書寫,因此較少使用;(3)所有函數都是Function的實例(對象);(4)函數也屬於對象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
//函數的定義方式
//1.自定義函數(命名函數)
function fn() {};
//2.函數表達式(匿名函數)
var fun = function() {};
//3.利用new Function('參數1', '參數2', '參數3')
var f = new Function('a', 'b', 'console.log(a + b)');
f(1, 2);
console.dir(f);
console.log(f instanceof Object); //true
</script>
</body>
</html>
1.2函數的調用方式
1.普通函數
2.對象的方法
3.構造函數
4.綁定事件函數
5.定時器函數
6.立即執行函數
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button>點擊</button>
<script>
var btn = document.querySelector('button');
//函數的調用方式
//1.普通函數
function fn() {
console.log(1);
}
// fn();
// fn.call();
//2.對象的方法
// var o = {
// sayHi: function() {
// console.log(11);
// }
// }
// o.sayHi();
//3.構造函數
function Star() {
console.log(22);
};
new Star();
//4.綁定事件函數
btn.onclick = function() {
console.log(33);
};
//5.定時器函數
setInterval(function() {}, 1000); //定時器1秒調用一次
//6.立即執行函數
(function() {
console.log(44);
})()
//立即執行函數是自動調用
</script>
</body>
</html>
2.this
2.1函數內this的指向
這些this的指向,是當我們調用函數的時候確定的。調用方式的不同決定了this的指向不同,一般指向我們的調用者
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button>點擊</button>
<script>
var btn = document.querySelector('button');
//函數的調用方式
//1.普通函數 this指向window
function fn() {
console.log('普通函數的this' + this);
}
fn();
// fn();
// fn.call();
//2.對象的方法 this指向的是對象 o
var o = {
sayHi: function() {
console.log('對象方法的this:' + this);
}
}
o.sayHi();
//3.構造函數 this指向ldh這個實例對象 原型對象裏面的this指向的也是ldh這個實例對象
function Star() {
console.log(22);
};
Star.prototype.sing = function() {}
var ldh = new Star();
//4.綁定事件函數 this 指向的是函數的調用者 btn這個按鈕
btn.onclick = function() {
console.log('綁定函數的this:' + this);
};
//5.定時器函數 this指向的也是window
setInterval(function() {
console.log('定時器的this:' + this);
}, 1000); //定時器1秒調用一次
//6.立即執行函數 this 指向的是window
(function() {
console.log('立即執行函數的this:' + this);
})()
//立即執行函數是自動調用
</script>
</body>
</html>
2.2改變函數內部this指向
JavaScript爲我們專門提供了一些函數方法來幫我們更優雅的處理內部this的指向問題,常用的有bind()、call()、apply()三種方法。
1.call方法
call()方法調用一個對象。簡單理解爲調用函數的方式,但是它可以改變函數的this指向。
- thisArg:在fun函數運行時指定的this值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
//改變函數this指向 js提供了三種方法 call() apply() bind()
//1.call()
var o = {
name: 'andy'
}
function fn(a, b) {
console.log(this);
console.log(a + b);
};
fn.call(o, 1, 2);
//call 第一個可以用來調用函數 第二個可以改變函數內this指向
//call 的主要作用可以實現繼承
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);
}
var son = new Son('張三', 18, '男');
console.log(son);
</script>
</body>
</html>
2.apply方法
apply()方法調用一個函數。簡單理解爲調用函數的方式,但是它可以改變函數的this指向。
- thisArg:在fun函數運行時指定的this值
- argsArray:傳遞的值,必須包含在數組裏面
- 返回值就是函數的返回值,因爲它就是調用函數
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
//2.apply() 應用 運用的意思
var o = {
name: 'andy'
};
function fn(arr) {
console.log(this);
console.log(arr); //打印出來的是字符串
};
fn.apply(o, ['pink']);
//1.也是調用函數 第二個可以改變函數內部的this指向
//2.但是他的參數必須是數組(僞數組)
//3.apply的主要運用 比如說我們可以利用apply 藉助於數學內置對象求最大值
var arr = [1, 66, 3, 99, 4];
var max = Math.max.apply(Math, arr);
var min = Math.min.apply(Math, arr);
console.log(max);
console.log(min);
</script>
</body>
</html>
3.bind方法
bind()方法不會調用函數,但是能改變函數內部this指向
- thisArg:在fun函數運行時指定的this值
- arg1, arg2:傳遞的其他參數
- 返回由指定的this值和初始化參數改造的原函數拷貝
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button>點擊</button>
<script>
//bind() 綁定 捆綁的意思
var o = {
name: 'andy'
};
function fn(a, b) {
console.log(this);
console.log(a + b);
};
var f = fn.bind(o, 1, 2);
f();
//1.不會調用原來的函數 可以改變原來函數內部的this指向
//2.返回的是原函數改變this之後產生的新函數
//3.如果有的函數我們不需要立即調用 但是又想改變這個函數內部的this指向此時用bind
//4.我們有一個按鈕,當我們點擊了之後,就禁用這個按鈕,3秒鐘之後開啓這個按鈕
var btn = document.querySelector('button');
btn.onclick = function() {
this.disabled = true; //this指向btn
setTimeout(function() {
this.disabled = false; //定時器裏面的this指向的是window
}.bind(this), 3000); //這個this指向的是btn這個對象
}
</script>
</body>
</html>
2.3call apply bind 總結
相同點:
都可以改變函數內部指向
區別點:
1.call和apply會調用函數,並且改變函數內部this指向
2.call和apply傳遞的參數不一樣,call傳遞參數aru1, aru2…形式,apply必須數組形式[arg]
3.bind不會調用函數,可以改變函數內部this指向
主要應用場景:
1.call經常做繼承
2.apply經常跟數組有關係,比如藉助於數學對象實現數組最大值最小值
3.bind不調用函數,但是還想改變this指向,比如改變定時器內部的this指向