this 值的总结
一、函数字面量(function literal)
// 创建一个名为 add 的变量,并用来把两个数字相加的函数值赋值给它
var add = function (a, b) {
return a + b;
}
函数字面量分为四个部分:
- 保留字 function
- 函数名,可以被省略
- 作用:可以通过自己的名字来调用自己,也可以被调试器和开发工具用来识别函数。
- 省略函数名后,被称为 匿名函数(anonymous)
- 包围在圆括号中的一组参数
- 包围在花括号中的一组语句
总结:函数字面量可以出现在任何允许表达式出现的地方。函数也可以被定义在其他函数中,一个内部函数除了可以访问自己的参数和变量,同时它也能自由访问把它嵌套阿紫其中的父函数中的参数和变量。
二、函数调用
在 JavaScript 中,函数一共有 4 种调用模式,这些模式在如何初始化 this 存在差异:
对象的方法调用方式
当一个函数被保存为对象的一个属性时,称为 方法
// 创建 objectExample 对象,其拥有 name 属性,sayName() 方法
// sayName() 方法中,this 为自己所属的对象(objectExample)
var objectExample = {
name: "test",
sayName: function () {
return this.name;
}
};
console.log(objectExample.sayName()); // test
函数调用模式
this 被绑定到全局对象
// 全局变量 name
// 创建 objectExample 对象,其拥有 name 属性,sayName() 方法
var name = "The Window";
var objectExample = {
name: "The Object",
sayName: function () {
var innerFun = function () {
alert(this.name);
}();
}
};
objectExample.sayName(); // The Window
构造器调用模式
如果在函数前面带上 new 调用则会创建一个连接到该函数的 prototype 成员的新对象,同时 this 会被绑定到新对象上。
// 创建 Example 对象,其拥有 name 属性,为其原型添加 sayName() 方法
var Example = function(string) {
this.name = string;
};
Example.prototype.sayName = function () {
console.log(this.name);
}
var nE = new Example("Surprise");
nE.sayName(); // Surprise
apply 调用模式
// 创建 Example 对象,其拥有 name 属性,为其原型添加 sayName() 方法
var Example = function(string) {
this.name = string;
};
Example.prototype.sayName = function () {
console.log(this.name);
}
// 构造一个包含 status 成员的对象
var nameObject = {
name: "Jim"
};
// nameObject 并没有继承自 Example.prototype,但是可以在 nameStatus 上
// 调用 sayName() 方法,尽管 nameObject 并没有一个名为 sayName() 的方法
var name = Example.prototype.sayName.apply(nameObject);
console.log(name); // Jim
三、this 指向全局变量
匿名函数
var name = "The Window";
var objectExample = {
name: "The Object",
sayName: function () {
return function () { // 匿名函数
return this.name
};
}
};
console.log(objectExample.sayName()()); // The Window
全局作用域
var name = "The Window";
function sayName () {
alert(this.name);
}
sayName(); // The Window
参考图书
《JavaScript语言精粹》
《JavaScript高级程序设计》