前言:
Javascript中的函数和由函数带出的作用域~~
函数是一块Javascript代码,被定义一次,但是可以被执行和调用多次。
JS中的函数也是对象,所以JS函数可以像其它对象那样操作和传递,所以我们也常叫JS中的函数为函数对象。
函数
函数中的几个部分:
- 函数名
- 参数列表
- 函数体
🌰:
1 | function foo(x, y) { |
楼上,foo是函数名,花括号内是函数题,圆括号内是参数列表。
函数的几个比较重要的点:
- this
- arguments
- 作用域
- 不同调用方式
- 不同创建方法
不同的调用方式
直接调用:
1 | foo(); |
对象方法:
1 | o.method(); |
构造器:
1 | new Foo(); |
call/apply/bind:
1 | func.call(o); |
不同创建方法(函数声明与表达式和函数构造器)
看几个例子:
function开头比较单纯的这种叫做函数声明:
1 | function add(a, b) { |
这样赋值一般的叫做函数表达式:
1 | var add = function(a, b) { |
这样声明了之后立即调用也叫做表达式:
1 | (function() { |
这样的也叫做表达式:
1 | return function() { |
这样有名字的赋值叫做命名函数表达式:
1 | var add = function foo(a, b) { |
命名函数表达式我们要注意,右边这个名字,在比较新的浏览器里面,我们是访问不到的。
在一些老的浏览器里面,可以访问的到,但是它指向的和左边的竟然不是一个东西。
这个很诡异,注意一下就好了。
函数声明与函数表达式最大的区别就是函数声明会被前置
还有一种方法是用Function构造器来创建一个函数:
1 | var func = new Function("a", "b", "console.log(a+b)"); |
或者:
1 | var func = Function("a", "b", "console.log(a+b)"); |
楼上这样的,构造器的前面是形参,最后一个参数是函数体。
Function构造器创建出的函数,可以拿到全局变量,但是拿不到它外层的函数中的变量,因此很少使用
用个图来总结一下:
this
this比较灵活,根据环境的不同,this会发生变化。
全局的this
全局下的this就是指向全局对象,浏览器中,就是window。
🌰:
1 | console.log(this.documeng === document); // true |
一般函数的this(浏览器)
一般函数中的this仍然指向全局对象window:
1 | function f1() { |
在nodejs中,就是global object啦~~~
需要注意,严格模式下,函数中的this指向undefined~~
作为对象方法的函数的this
指向调用它的对象:
1 | var o = { |
注意指向的是调用它的对象,为了强调这一点:
1 | var o = {props: 37}; |
对象原型链上的this
仍然指向调用它的那个对象。
🌰:
1 | var o = {f: function() { return this.a + this.b } }; |
构造器中的this
当我们用new 构造函数()的形式调用构造函数的时候,里面的this指向一个以该构造函数为原型的新对象。
🌰:
1 | function MyClass() { |
注意当我们有return了一个对象的的时候,以return的那个对象为准。
没有return一个对象的时候,默认this就是return的东西。
call/apply方法与this
call/apply方法可以用来修改this。
1 | function add(c, d) { |
注意call和apply的效果是一样的,第一个参数是this指向的对象,后面的参数就是函数正常的传参。
不同的是call中就是按顺序把参数写进去,但是apply当中需要把参数以数组形式传入。
bind方法与this
bind方法是ES5才开始提供的。
也是用来修改this的指向,然后,注意它只是修改指向,并不调用函数。
🌰:
1 | function f() { |
它和apply和call最明显的区别就是,调用的这个操作的主动权在我们手上,我们让它什么时候执行,它就什么时候执行。
还有一点,它很“顽固”。就是当我们用bind绑定过了this之后,它就算被当作别的对象的方法调用,this也不会改变,除非你再次调用bind修改。
🌰:
1 | var o = {a:37, f:f, g:g}; |
总结
啊,这篇文章我觉得最重要的还是后半部分的this啦~~
要熟悉啊要熟悉!
下一篇开始写arguments~~~^_^