js高级教程阅读笔记 第五章-引用类型(5.6)

函数内部属性

函数中有两个特殊的对象。

  • arguments:它包含了所有的参数,重要的是它的一个叫做callee的属性,用于指向拥有这个参数的函数。好处是什么呢

实例:

function fa(num){
  if(num<=1){
    return 1;
  }else{
    return num*fa(num-1);
  }

}
alert(fa(3));//6

这是一个普通的递归调用,但是却高度耦合,即严重依赖fa()。
但是使用了arguments.cellee(个人理解就是用这个可以代替函数名),就可以随意更换函数名了。

实例:

function fa(num){
  if(num<=1){
    return 1;
  }else{
    return num*arguments.callee(num-1);
  }

}

var fal = fa;  //随意更改函数名
alert(fa(3));//6
alert(fal(3));//6

之所以能这样使用,是因为callee本身是一个指针。

  • this:和java以及c的this含义大致一直,就是指当前所指的对象。

我们用实例来解释:

window.color = 'red';
var o = {color:'blue'};

function sayColor(){
  alert(this.color);
}


sayColor(); //red
o.sayColor = sayColor; //没有()的函数名就是指针,这里把指针交给0.sayColor
o.sayColor();  //blue

sayColor作用与全局,而js中全局都是用window指代,所以直接调用sayColor的到的是red。
第二点,非常重要的一点,因为在js中,函数名本身其实就是一个指针,所以无论谁指向它都一样

  • 函数对象的另一个属性caller,用于保存当前函数的引用(调用)。

下面是实例:

function outer(){
  inner();
}

function inner(){
  alert(inner.caller);
}

outer();

输出:

function outer(){
  inner();
}

即inner的引用。
之前学习了arguments.callee这里也可以用,使得更为松散的耦合。

function outer(){
  inner();
}

function inner(){
  alert(arguments.callee.caller);
}

outer();

函数的属性和方法

函数既然是对象,就具有属性和方法。通用的属性是length和prototype。

length表示函数接收参数的个数:

function add(num1,num2){
  return num1+num2;
}

alert(add.length);  //2个参数

prototype在第六章

apply()和call()

apply实例:

function sum(num1,num2){
  return num1+num2;
}

function callSum(num1,num2){
  return sum.apply(this,arguments);  //this是当前作用域范围(window,因为是在全局作用域中调用的)
}
function callSum2(num1,num2){
  return sum.apply(this,[num1,num2]);
}

alert(callSum(10,10));  //20
alert(callSum(10,10));  //20

call()唯一的不同是除了第一个this参数,其他传递参数必须一个个列举出来,实例:

function sum(num1,num2){
  return num1+num2;
}

function callSum(num1,num2){
  return sum.call(this,num1,num2);  
}

alert(callSum(10,10)); //20

其实apply和call真正的作用是扩充函数的作用域。
实例:

window.color = 'red';
var o = {color:'blue'};

function sayColor(){
 alert(this.color); 
}

sayColor.call(this);//red
sayColor.call(window);//red
sayColor.call(o);//blue

由上,本来sayColor是全局定义的函数,但是使用了call,在第三个调用中,使得结果为blue

bind()

bind用于创建实例函数,并且把this的值绑定在bind的函数上。
实例:

window.color = 'red';
var o = {color:'blue'};

function sayColor(){
 alert(this.color); 
}

var newSayColor = sayColor.bind(o);
newSayColor();//blue

基本包装类型

我们知道基本类型本来是不具备方法的,但是很高兴的是ecmascript提供了基本类型包装。
什么意思呢:当访问基本类型的时候,会创建一个基本类型的实例,在实力上调用方法,最后消除实例。这就使得基本类型和字符串一样了。

引用类型和基本类型的区别就是生存周期,引用类型会一直存在内存中,而基本类型包装则会在执行瞬间销毁

posted on 2017-08-09 11:09  I_noname  阅读(99)  评论(0编辑  收藏  举报

导航