JavaScript函数
一、函数定义的基本形式
1.函数声明方式 function 关键字(命名函数)
函数声明的同时JS引擎还定义了一个与函数名同名的变量,我们在调用这个函数的时候实际上是在使用这个变量,
且它可以在函数声明之前调用
// 不带参数的函数
function say(){
console.log('hello');
}
say() // hello
// 带参数的函数 // 计算任意两个整数和
function sun(a,b){
console.log(a+b);
}
sun(1,2) // 3
// 带返回值的函数 // 计算两个整数的乘积
function mod(a,b){
return a*b
}
console.log(mod(2,5)); // 第一种输出方法 10
var res=mod(2,5); // 第二种输出方法 10
console.log(res);
2.函数表达式(匿名函数)
此时将匿名函数赋值给了一变量,此变量需在定义后使用
var fn=function(a){
console.log(a);
}
fn(2); // 2
3.new Function()
这种方式效率低,每次执行函数的时候,其函数体都会被解析一次。此外这样声明的函数是不会继承当前声明位置
的作用域,它默认只会拥有全局作用域
var myFunction = function (a, b) {
return a * b
};
var x = myFunction(4, 3); // 12
二、函数的参数类型
<script>
/**最新的 ECMAScript 标准定义了 8 中数据类型
* 7中原始类型
* Boolean、Null、Undefined、Number、BigInt、String、Symbol
* 和1中复杂类型 Object
* 函数的参数类型
*/
function fn(a){
console.log(a);
}
fn(2) // 2
fn('hello') // hello
fn(true) // true
fn(null) // null
fn(undefined) // undefined
fn([1,2,3]) // Array(3)
fn({name:'lkr'}) // Object name:'lkr'
</script>
三、函数的使用场景
<body>
<button>按钮</button>
<script>
function ajax(){
console.log('ajax'); // ajax
}
ajax()
// 作为对象中的属性的值
var a={
sayHi:function(){
console.log('hello'); // hello
} // 相当于 var sayHi=function(){ console.log('hello'); }
}
a.sayHi()
// 构造函数
function Star(name){
this.name=name
}
var s1=new Star('邓伦')
console.log(s1); // 邓伦
// 作为事件的处理函数
document.querySelector('button').addEventListener('click',function(){
console.log('点击了按钮'); // 点击按钮控制器显示:点击了按钮
})
document.querySelector('button').onclick=function(){
console.log('点击了按钮');// 点击按钮控制器显示:点击了按钮
}
// 定时器中的函数
setTimeout(function(){
console.log('3秒时间到'); // 3秒后控制器显示 3秒时间到
},3000)
// 立即执行函数
(function() {
console.log('立即执行,不需要调用'); // 立即执行,不需要调用
})()
</script>
</body>
四、this指向
1.函数内部的this指向
这些 this 的指向,是当我们调用函数的时候确定的。调用方式的不同决定了this 的指向不同一般指向我们的调用者.
调用方式 | this指向 |
---|---|
普通函数使用 | window |
构造函数使用 | 实例对象,原型对象里面的方法也指向实例对象 |
对象方法调用 | 该方法所属对象 |
事件绑定方法 | 绑定事件对象 |
定时器函数 | window |
立即执行函数 | window |
<body>
<button>按钮</button>
<script>
/**
* 1) 普通函数中,this指向window
* 2) 在定时器中,this指向window
* 3) 调用函数的对象,this指向当前对象
* 4) 该方法所属对,this指向对象本身
* 5) 立即执行函数,this指向window
* 6) 作为事件的绑定方法,this指向绑定的事件对象
*/
function f1(){
console.log(this); // 输出window
}
f1()
setTimeout(function(){
console.log(this); // 输出window
},3000)
//定时器及时放到一个函数中,this也指向window
function f2(){
setTimeout(function(){
console.log(this); // 输出window
},3000)
}
// 调用函数的对象 this指向当前对象
function Star(name){
console.log(this);
this.name=name
}
var s1=new Star('胡宇桐')
// 该方法所属对,this指向对象本身
var a={
sayHi:function(){
console.log(this.name);
}
}
// 立即执行函数,this指向window
(function() {
console.log(this);
})()
// 作为事件的处理函数
document.querySelector('button').addEventListener('click',function(){
console.log(this); // 点击按钮控制器显示:点击了按钮
})
</script>
</body>
2.改变this指向的三种方式
1.call
call 方法可以指定this 的指向(即函数执行时所在的的作用域),然后再指定的作用域中,执行函数
call 方法的参数,应该是对象obj,如果参数为空或null,undefind,则默认传参全局对象
function f1(){
// 原来this指向window
console.log(this);
}
var a={}
// 给call传入一个值,这是this指向传入的值,这是指向的是a的空值
f1.call(a)
call 可以接受多个参数,第一个参数是this 指向的对象,之后的是函数回调所需的入参
function f1(a,b){
console.log(this);
console.log(a,b);
}
var a={}
f1.call(a,1,2)
// 第一个参数指向a的空值,之后的参数值返回1,2
2.apply
apply 和call 作用类似,也是改变this 指向,然后调用该函数,唯一区别是apply 接收数组作为函数执行时的参数
function f1(a,b){
console.log(this);
console.log(a,b);
}
var a={}
f1.apply(a,[3,4])
// 输出一个空值,和3,4
3.bind
bind 用于将函数体内的this绑定到某个对象,然后返回一个新函数
function f1(a,b){
console.log(this);
console.log(a,b);
}
var a={}
var fn=f1.bind(a,5,6);
fn();
// 输出一个空值,和5,6
call、apply、bind三者的异同
共同点:
- 都可以改变this指向
不同点:
- call 和 apply 会调用函数, 并且改变函数内部this指向
- call 和 apply传递的参数不一样,call传递参数使用逗号隔开,apply使用数组传递
- bind 不会调用函数, 可以改变函数内部this指向
应用场景:
- call 经常做继承
- apply经常跟数组有关系. 比如借助于数学对象实现数组最大值最小值
- bind 不调用函数,但是还想改变this指向. 比如改变定时器内部的this指向