笔记 04 JS 函数 – 声明,表达式,this
函数
函数是JavaScript中的一等对象
=> 可以把函数像其它值一样传递。
1 函数声明与表达式
1 函数声明
存在于当前上下文的任意一个地方,
方法会在执行前被解析
foo(); // 正常运行,因为foo在代码运行前已经被创建
function foo() {}
2 函数赋值表达式
/**
* 由于var定义了一个声明语句,
* 对变量foo的解析是在代码运行之前,
* foo变量在代码运行时已经被定义过了。
* 但是由于赋值语句只在运行时执行,
* 因此在相应代码执行之前,foo的值缺省为undefined
*/
foo; // 'undefined'
foo(); // 出错: TypeError: foo is not a function
var foo = function() {};
3 命名函数的赋值表达式
/**
* 神奇的递归死循环
* 实践方法-函数自执行 (function bar() { console.log(1); bar(); })()
*/
var foo = function bar() {
console.log(1);
bar(); // 正常运行
}
/**
* bar函数声明外市不可见的。
* 这是因为我们已经把函数赋值给了 foo
* 然而在 bar 内部依然可见。
* 这是由于 JavaScript 的命名处理所致,
* 函数名在函数内总是可见的。
*/
bar(); // 在外边调用不起来
2 this的工作原理
JavaScript有一套完全不同于其它语言的对this的处理机制。
1 全局范围内
this; // 它将会指向全局对象
2 函数调用
ES5 注意
: 在严格模式下(strict mode),不存在全局变量。 这种情况下 this 将会是 undefined。
foo(); // 函数内部this指向全局对象
3 方法调用
test.foo(); // 方法内部this指向test对象
4 调用构造函数
/**
* 如果函数倾向于和new关键词一块使用,
* 则我们称这个函数是 构造函数
*/
new foo(); // 在构造函数内部this指向新创建的对象
5 显式的设置this
apply,call 等函数
/**
* 当使用 Function.prototype 上的 call 或者 apply 方法时
* 函数内的 this 将会被 显示设置为 `函数调用的第一参数`
*/
function foo(a, b, c) {};
var bar = {};
foo.apply(bar, [1, 2, 3]); // 数组将会被扩展,如下所示
foo.call(bar, 1, 2, 3); // 传递到foo的参数是: a = 1, b = 2, c = 3
// 在 foo函数内 this被设置成了bar
误区 - 例子1
Foo.method = function() {
function test() {
// this 将会被设置为全局对象 (浏览器环境中也就是 window 对象)
}
test();
}
/**
* 为了在 test 中获取 Foo 对象的引用,
* 我们需要在 method 函数内部创建一个局部变量
* 指向 Foo 对象
*/
Foo.method = function() {
var that = this;
function test() {
// 使用 that 来指向 Foo 对象
}
test();
}
误区 - 例子2
/**
* test 就像一个比普通函数调用被调用
* 因此,函数内的 this 将不在被指向到
* someObject 对象。
*/
var test = someObject.methodTest;
test();
function Foo() {};
Foo.prototype.method = function() {};
function Bar() {};
Bar.prototype = Foo.prototype;
new Bar().method(); // 当 method 被调用是,this 将指向 Bar 的实例对象