第三章:ES6基础(下)
3.1:函数的定义和调用
-
函数的定义方式
- 函数声明方式
function
关键字(命名函数) - 函数表达式(匿名函数)
new Function()
var fn = new Function('参数1', '参数2'...., '函数体');
Function
里面参数都必须是字符串格式。- 第三种方式执行效率低,也不方便书写,因此较少使用。
- 所有函数都是
Function
的实例(对象)。 - 函数也属于对象。
- 函数声明方式
-
函数的调用方式
-
普通函数
function fn() { console.log('小王要努力学习'); } fn(); fn.call();
-
对象的方法
var o = { sayHi: function () { console.log('小王要努力学习'); } } o.sayHi();
-
构造函数
function Star() { }; new Star();
-
绑定事件函数
btn.onclick = function () { };
-
定时器函数
setInterval(function () { }, 1000);
-
立即执行函数
(function () { console.log('人生的巅峰'); })();
-
3.2:this
-
函数内
this
的指向这些
this
的指向,是当我们调用函数的时候确定的。调用方式的不同决定了this
的指向不同。一般指向我们的调用者:
调用方式 this指向 普通函数调用 window 构造函数调用 实例对象,原型对象里面的方法也指向实例对象 对象方式调用 该方法所属对象 事件绑定方式 绑定事件对象 定时器函数 window 立即执行函数 window -
改变函数内部
this
指向JavaScript为什么专门提供了一些函数方法来帮我们更优雅的处理函数内部
this
的指向问题,常用的有bind()
、call()
、apply()
。-
call()
call()
方法调用一个对象。简单理解为调用函数的方式,但是它可以改变函数的this指向。fun.call(thisArg, arg1, arg2, ....);
thisArg
:在fun
函数运行时指定的this
值。arg1
、arg2
:传递的其他参数。- 返回值就是函数的返回值,因为它就是调用函数。
- 因此当我们想改变
this
指向,同时想调用这个函数的时候,可以使用call
,比如继承。
-
apply()
apply()
方法调用一个函数。简单理解为调用函数的方式,但是它可以改变函数的this指向。fun.apply(thisArg, [argsArray])
thisArg
:在fun
函数运行时指定的this
值。argsArray
:传递的值,必须包含在数组里面。- 返回值就是函数的返回值,因为它就是调用函数。
- 因此
apply
主要跟数组有关系,比如使用Math.max()
求数组的最大值。
-
bind()
bind()
方法不会调用函数。但是能改变函数内部this指向。fun.bind(thisArg, arg1, arg2, ...)
thisArg
:在fun
函数运行时指定的this
值。arg1
、arg2
:传递的其他参数。- 返回由指定的
this
值和初始化参数改造的原函数拷贝。 - 因此当我们只是想改变
this
指向,并且不想调用这个函数的时候,可以使用bind
。
-
3.3:严格模式
-
什么是严格模式
javaScript
除了正常模式外,还提供了严格模式(strict mode
)。ES5
的严格模式是采用具有限制性,javaScript
变体的一种方式,即在严格的条件下运行JS代码。严格模式在
IE10
以上版本的浏览器中才会被支持,旧版本浏览器中会被忽略。严格模式对正常的
javaScript
语义做了一些更改。- 消除了
javascipt
语法的一些不合理、不严谨之处,减少了一些怪异行为。 - 消除代码运行的一些不安全之处,保证代码运行的安全。
- 提高编译效率,增加运行速度。
- 禁用了在
ECMAScript
的未来版本可能会定义的一些语法,为未来新版本的javascript
做好铺垫。比如一些保留字如:class
、enum
、extends
、import
、super
不能做变量名。
- 消除了
-
开启严格模式
严格模式可以应用整个脚本或个别函数中。因此在使用时,我们可以将严格模式分为脚本开启严格模式和为函数开启严格模式两种情况。
-
为脚本开启严格模式
为整个脚本文件开启严格模式,需要在所有语句之前放一个特定语句
'use strict'
。(单向引号都可以)<script> 'use strict'; </script> <script> (function () { 'use strict'; })() </script>
-
为函数开启严格模式
要给某个函数开启严格模式,需要把
'use strict'
。声明放在函数体所有语句之前。<script> function fn() { 'use strict'; } function fun() { } </script>
将
use strict
放在函数体的第一行,则整个函数以严格模式运行。
-
-
严格模式中的变化
严格模式对
javascript
的语法和行为,都做了一些改变。-
变量规定
- 在正常模式中,如果一个变量没有声明就赋值,默认是全局变量。严格模式禁止这种用法,变量都必须先用
var
命令声明,然后再使用。 - 严禁删除已经声明变量。
- 在正常模式中,如果一个变量没有声明就赋值,默认是全局变量。严格模式禁止这种用法,变量都必须先用
-
严格模式下
this
指向问题- 以前在全局作用域函数中的
this
指向window
对象。 - 严格模式下全局作用域中函数中的
this
是undefined
。 - 以前构造函数时不加
new
也可以调用,当普通函数,this
指向全局对象。 - 严格模式下,如果构造函数不加
new
调用,this
指向的是undefined
如果给他赋值则会报错。 new
实例化的构造函数指向创建的对象实例。- 定时器
this
还是指向window
。 - 事件、对象还是指向调用者。
- 以前在全局作用域函数中的
-
函数变化
-
函数不能有重名的参数。
-
函数必须声明在顶层。新版本的
javascript
会引入"块级作用域"(ES6中以引入)。为了与新版本接轨,不允许在非函数的代码块内声明函数。if (true) { function f() { } // !!! 语法错误 f(); } for (var i = 0; i < 5; i++) { function f2() { } // !!! 语法错误 f2(); } function baz() { // 合法 function eit() { } // 同样合法 }
-
-
3.4:高阶函数
高阶函数是对其他函数进行操作的函数,它接收函数作为参数或将函数作为返回值输出。
// 情况一
function fn(callback) {
callback &7 callback();
}
fn(function() {});
// 情况二
function fn() {
return function() {}
}
fn();
此时fn
就是一个高阶函数。函数也是一种数据类型,同样可以作为参数使用。最典型的就是作为回调函数。同理函数也可以作为返回值传递回来。
3.5:闭包
-
变量的作用域
变量根据作用域的不同分为两种:全局变量和局部变量。
- 函数内部可以使用全局变量。
- 函数外部不可以使用局部变量。‘
- 当函数执行完毕,本作用域内的局部变量会销毁。
-
什么是闭包
闭包
closure
指有权访问另一个函数作用域中变量的函数。简单理解就是:一个作用域可以访问另外一个函数内部的局部变量。
function fn1() { var num = 10; function fn2() { console.log(num); } fn2(); } fn1();
-
闭包的作用
闭包作用:延伸变量的作用范围。
3.6:递归
-
什么是递归
如果一个函数在内部可以调用其本身,那么这个函数就是递归函数。
简单理解:函数内部自己调用自己,这个函数就是递归函数。
递归函数的作用跟循环效果一样,由于递归很容易发生”栈溢出“错误(stack overflow),所以必须要加退出条件
return
。 -
浅拷贝和深拷贝
- 浅拷贝只是拷贝一层,更深层次对象级别的只拷贝引用。
- 深拷贝拷贝多层,每一级别的数据都会拷贝。
Object.assign(target, ...sources)
es6新增方法可以浅拷贝。