1、函数的定义和调用
1.1函数的定义方式
1、自定义函数(命名函数)
2、函数表达式(匿名函数)
3、利用 new Function (‘参数1’, ‘参数2’, ‘函数体’)
1、自定义函数(命名函数)
function fn() {}
2、函数表达式(匿名函数)
var fun = function() {}
3、利用 new Function ('参数1', '参数2', '函数体')
var f = new Function('a', 'b', 'console.log(a + b)')
所有函数都是 Function 的实例(对象)
1.2函数的调用方式
1、普通函数
2、对象的方法
3、构造函数
4、绑定事件函数
5、定时器函数
6、立即执行函数
1、普通函数
function fn() {
// this指向window
console.log('Hello World!', this)
}
fn();
// fn.call()
2、对象的方法
var o = {
sayHi: function() {
// this指向o
console.log('快乐', this)
}
}
o.sayHi()
3、构造函数
function Star() {}
// this指向 ldh这个实例对象,原型对象里面的this也指向ldh这个实例对象
var ldh = new Star();
Star.prototype.sing = function() {}
4、绑定事件函数
// this指向函数的调用者 btn
btn.onclick = function() {} // 点击调用
5、定时器函数
// this指向window
setInterval(function() {}, 1000) // 1s调用一次
6、立即执行函数
(function() {
console.log('立即执行') // 立即执行函数是自动调用
})()
2、this
2.1函数内this的指向
2.2改变函数内部this指向
3种方法:call()、apply()、bind()
1、call()
var o = {
name: 'andy'
}
function fn(a, b) {
// 原本指向window,添加fn.call(o)后指向了o
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)
2、apply()
var o = {
name: 'andy'
}
function fn(arr) {
// 原本指向window,添加fn.apply(o)后指向了o
console.log(this)
console.log(arr)
}
fn.apply(o, ['pink'])
// apply作用: 第一个可以调用函数,第二个可以改变函数内的this指向
// 参数必须是数组
// apply的主要应用,比如说可以借用数学内置对象求最大值
var arr = [1, 0, 99 ,3]
var max = Math.max.apply(Math, arr)
3、bind()
var o = {
name: 'andy'
}
function fn(a, b) {
// 原本指向window
console.log(this)
console.log(a + b)
}
var f = fn.bind(o, 1, 2)
f()
// 不会调用原来的函数,但能改变this指向
// 返回的是原函数改变this之后产生的新函数
// 应用: 如果有的函数不需要立即调用,但是又要改变this指向(点击一个按钮之后,禁用按钮,3秒后开启按钮)
2.3call apply bind 总结
相同点:
都可以改变函数内部的this指向
区别点:
1、call和apply会调用函数,并且改变函数内部的this指向
2、call和apply传递的参数不一样,call传递参数aru1,aru2…形式,apply必须数组形式[arg]
3、bind不会调用函数,可以改变函数内部this指向
主要应用场景:
1、call经常做继承
2、apply经常跟数组有关系,比如借助数学对象实现数组最大值最小值
3、bind不调用函数,但还是想改变this指向,比如改变定时器内部this指向
3、严格模式
3.1 介绍
严格模式在IE10以上版本的浏览器才会被支持,旧版本浏览器会被忽略,采用正常模式。
严格模式对正常的javascript语义做了一些更改:
1、消除了javascript语法的一些不合理,不严谨之处;
2、消除代码运行的一些不安全之处;
3、提高编译器效率;
4、不允许使用一些保留字:class、enum等做变量名;
3.2 开启严格模式
严格模式应用到整个脚本或个别函数中,因此在使用时,我们将严格模式分为为脚本开启严格模式和为函数开启严格模式两种情况。
1、为脚本开启严格模式: 在所有语句之前放一个"use strict"
<script>
"use strict"
console.log("这是严格模式")
</script>
// 如果是立即执行函数
<script>
(function(){
"use strict"
var num = 10
function fn() {}
})()
</script>
2、为函数开启严格模式: 在函数中放一个"use strict"
<script>
function fn(){
"use strict"
// 下面代码按照严格模式执行
}
function fun(){
// 里面按照普通模式执行
}
</script>
3.3 严格模式中的变化
1、变量规定
①在正常模式下,如果一个变量没有声明就赋值,默认是全局变量。严格模式下禁止这种用法,必须先声明再使用;
②不能随意删除已经声明好的变量,例如:delete x;语法是错误的;
2、严格模式下this指向问题
③以前全局作用域中this指向window,严格模式下this是undefined;
④严格模式下,如果构造函数不加new调用,this会报错;如果new的话,指向创建的对象实例,不报错;
⑤定时器this还是指向window;
⑥事件、对象还是指向调用者;
3、函数变化
⑦函数不能有重名参数;
⑧不允许在非函数的代码块(if、for等)中声明函数
4、高阶函数
高阶函数是对其它函数进行操作的函数,他接收函数作为参数或将函数作为返回值输出。
函数也是一种数据类型,同样可以作为参数,最典型的就是作为回调函数。
function fn(a, b, callback) {
console.log(a + b)
callback && callback()
}
fn(1, 2, function(){
console.log('我是最后调用的')
})
5、闭包
5.1 变量作用域
变量作用域不同分为两种:全局变量和局部变量
1、函数内部可以使用全局变量
2、函数外部不可以使用局部变量
3、当函数执行完毕,本作用域内的局部变量会销毁
5.2 什么是闭包
有权访问另一个函数作用域中变量,被访问变量的函数称为闭包。
闭包的主要作用:延伸了变量的作用范围
// fn外面的作用域可以访问fn内部的局部变量
function fn() {
var num = 10
function fun() {
console.log(num)
}
return fun
}
var f = fn()
f()