ECMAScript-Function

说明:本文中有借鉴其他大牛的文章,旨在共同学习,不做也不得作商用!

arguments属性

arguments是一个类数组对象,包含着传入函数中的所有参数,主要用途是保存函数参数,它不是一个数组,但是可以像数组一样取值,如:arguments[0].
但这个对象还有一个名叫callee的属性该属性是一个指针,指向拥有这个arguments对象的函数(可以理解为它自己)。
函数的caller属性:在一个函数调用另一个函数时,被调用函数会自动生成一个caller属性,指向调用他的函数对象。如果该函数未被调用,或并非被其他函数调用,则caller为null

//请看下面非常经典的阶乘函数
function fuctorial(num){
  if(num<=1){
    return 1;
  }else{
    return num *fuctorial(num-1);
  }
}

//这个函数的执行与函数名fuctorial紧紧耦合在了一起。为了消除这种紧密耦合的现象,这像下面这样使arguments.callee
function fuctorial(num){
  if(num<=1){
    return 1;
  }else{
    return num * arguments.callee(num-1);//
  }
}

//在这个重写后的 fuctorial()函数的函数体内,没有再引用函数名fuctorial。这样无论引用函数时使用的是什么名字,都可以保证正常完成递归调用。
var trueFuctorial = fuctorial;
fuctorial = function(){ return 0};

alert(trueFuctorial(5)); //120  这里涉及到引用对象的赋值
alert(fuctorial(5)); //0

bind()

bind()方法主要就是将函数绑定到某个对象上,改变函数this的指向。
bind()会创建一个函数。
函数体内的this对象的值会被绑定到传入bind()中的第一个参数的值,例如:f.bind(obj),实际上可以理解为obj.f(),这时f函数体内的this自然指向的是obj;

var a = {
    b: function() {
      console.log(this);  //a对象;因为 a.b() 这个函数的执行环境上下文是 a 对象
      var func = function() {
        console.log(this)  //window 对象; 因为 func() 函数执行的上下文环境是 window 对象
        console.log(this.c);  //undefined; 因为 window.c 是undefined
      }
      func();
    },
    c: 'hello'
}
a.b();
console.log(a.c);  //hello

改变 this 的指向问题
方式一:改变 this 的值

var a = {
    b: function() {
	  var _this = this;
      console.log(_this);  //a对象;因为 a.b() 这个函数的执行环境上下文是 a 对象
      var func = function() {
        console.log(_this)  //a对象;
        console.log(_this.c);  //hello
      }
      func();
    },
    c: 'hello'
}
a.b();
console.log(a.c);  //hello

方式二:绑定this的值发生改变


// 使用bind方法一
var a = {
	b: function() {
		var func = function() {
			console.log(this.c);
		}.bind(this);  //这里bind(this)的时候,这里的this指的是a对象的上下文环境,所以这时func的this对象就绑定到a上了
		func();
	},
	c: 'hello'
}
a.b(); // hello
console.log(a.c); // hello

// 使用bind方法二
  var a = {
    b: function() {
      var func = function() {
        console.log(this.c);
      }
      func.bind(this)();
    },
    c: 'hello'
  }
  a.b(); // hello
  console.log(a.c); // hello

//注意一下两点:
var a = {
	b: function() {
		var func = function() {
			console.log(this.c);
		};
		func.bind(this);//函数是一个对象,它有 bind() 等一些属性方法。 不能写成 func().bind(this); 
	},
	c: 'hello'
}
a.b(); // 这里不打印内容,因为bind()只是返回了一个函数,而 func.bind(this) 只是相当于得到了一个返回的函数,并没有执行。需要 改写成 func.bind(this)()
console.log(a.c); // hello

call()

方法的重用,可以编写能够在不同对象上使用的方法。
通过 call(),您能够使用属于另一个对象的方法。
语法:obj1.(method).call(obj2,argument1,argument2)就是 obj2 可以使用 obj1 中的方法

var person = {
    fullName: function() {
        return this.firstName + " " + this.lastName;
    }
}
var person1 = {
    firstName:"Bill",
    lastName: "Gates",
}
var person2 = {
    firstName:"Steve",
    lastName: "Jobs",
}
person.fullName.call(person1);  //person1调用person的的fullName 方法。 将返回 "Bill Gates"

call()方法可以传参,但是其参数只能从第二个开始,单个传入:

var person = {
  fullName: function(city, country) {
    return this.firstName + " " + this.lastName + "," + city + "," + country;
  }
}
var person1 = {
  firstName:"Bill",
  lastName: "Gates"
}
person.fullName.call(person1, "Seattle", "USA");

apply()

方法重用,能够编写用于不同对象的方法
apply()方法与call()很像.两者的区别就是传参的形式不一样而已.
语法:obj1.(method).call(obj2,argument1,argument2)就是 obj2 可以使用 obj1 中的方法

var person = {
    fullName: function() {
        return this.firstName + " " + this.lastName;
    }
}
var person1 = {
    firstName: "Bill",
    lastName: "Gates",
}
person.fullName.apply(person1);  //person1调用person对象的fullName方法, 将返回 "Bill Gates"

apply()方法也可以传入参数,但是其参数是从第二个开始,以数组的形式传入

var person = {
  fullName: function(city, country) {
    return this.firstName + " " + this.lastName + "," + city + "," + country;
  }
}
var person1 = {
  firstName:"John",
  lastName: "Doe"
}
person.fullName.apply(person1, ["Oslo", "Norway"]);

备注:call()方法与apply()方法要结合函数的arguments属性使用,更灵活

posted @ 2021-04-09 12:52  依梦维马  阅读(54)  评论(0)    收藏  举报