引 用 类 型
定义:引用类型是一种数据结构,用于将数据和功能组织在一起,引用类型有时候也被称为对象定义
Function 类型
- Function实例的创建
1. 函数声明 定义一个函数
function sum (num1, num2) {
return num1 + num2;
}
2. 函数表达式 声明一个函数
var sum = function(num1, num2){
return num1 + num2;
};
理解:
a. 函数名仅仅是指向函数的指针,使用不带圆括号的函数名是访问函数指针,而非调用函数
/* 由于函数名仅仅是指向函数的指针,因此函数名与包含对象指针的其他变量没有什么不同。
* 换句话说,一个函数可能会有多个名字
*/
function sum(num1, num2){
return num1 + num2;
}
alert(sum(10,10)); // 20
var anotherSum = sum;
alert(anotherSum(10,10)); // 20
sum = null;
alert(anotherSum(10,10)); // 20
b. 函数声明和函数表达式的区别:函数声明自动提升到顶部
/* 函数声明在代码开始执行之前,解析器就已经通过一个名为函数声明提升(function declaration hoisting)的过程,
* 读取并将函数声明添加到执行环境中。对代码求值时,JavaScript引擎在第一遍会声明函数并将它们放到源代码树的顶部。
* 所以,即使声明函数的代码在调用它的代码后面,JavaScript 引擎也能把函数声明提升到顶部。
*/
alert(sum(10,10)); // 20
function sum(num1, num2){
return num1 + num2;
}
alert(sum(10,10)); // “unexpected identifier”(意外标识符)错误
var sum = function(num1, num2){
return num1 + num2;
};
- 函数属性和方法
1. 函数内部属性: arguments 和 this
arguments:arguments 的主要用途是保存函数参数,但这个对象还有一个名叫 callee 的属性,
该属性是一个指针,指向拥有这个 arguments 对象的函数。
function factorial(num){
if (num <=1) {
return 1;
} else {
return num * factorial(num-1)
}
}
/* 定义阶乘函数一般都要用到递归算法;如上面的代码所示,
* 在函数有名字,而且名字以后也不会变的情况下,这样定义没有问题。
* 但问题是这个函数的执行与函数名 factorial 紧紧耦合在了一起。
* 为了消除这种紧密耦合的现象,可以像下面这样使用 arguments.callee
*/
function factorial(num){
if (num <=1) {
return 1;
} else {
return num * arguments.callee(num-1)
}
}
this:this引用的是函数据以执行的环境对象——
或者也可以说是 this 值(当在网页的全局作用域中调用函数时,this 对象引用的就是 window )。
window.color = "red";
var o = { color: "blue" };
function sayColor(){
alert(this.color);
}
sayColor(); // "red"
o.sayColor = sayColor;
o.sayColor(); // "blue"
caller:这个属性中保存着调用当前函数的函数的引用,如果是在全局作用域中调用当前函数,它的值为 null
function outer(){
inner();
}
function inner(){
alert(inner.caller);
}
outer(); // "function outer(){inner();}"
2. 函数属性和方法:
ECMAScript 中的函数是对象,因此函数也有属性和方法
length:length 属性表示函数希望接收的命名参数的个数
function sayName(name){
alert(name);
}
function sum(num1, num2){
return num1 + num2;
}
function sayHi(){
alert("hi");
}
alert(sayName.length); // 1
alert(sum.length); // 2
alert(sayHi.length); // 0
prototype :对于ECMAScript 中的引用类型而言, prototype 是保存它们所有实例方法的真正所在,
apply() :apply和call的用途都是在特定的作用域中调用函数,实际上等于设置函数体内 this 对象的值。
function sum(num1, num2){
return num1 + num2;
}
function callSum1(num1, num2){
return sum.apply(this, arguments); // 传入 arguments 对象
}
function callSum2(num1, num2){
return sum.apply(this, [num1, num2]); // 传入数组
}
alert(callSum1(10,10)); // 20
alert(callSum2(10,10)); // 20
call():在使用call() 方法时,传递给函数的参数必须逐个列举出来
function sum(num1, num2){
return num1 + num2;
}
function callSum(num1, num2){
return sum.call(this, num1, num2);
}
alert(callSum(10,10)); //20
bind():这个方法会创建一个函数的实例,其 this 值会被绑定到传给 bind() 函数的值
window.color = "red";
var o = { color: "blue" };
function sayColor(){
alert(this.color);
}
var objectSayColor = sayColor.bind(o);
objectSayColor(); // blue