第2章 this 、 call 和 apply

第一部分 基础知识

第2章  this 、 call 和 apply

2.1  this

  JavaScript的 this 总是指向一个对象,而具体指向哪个对象是在运行时基于函数的执行环境动态绑定的,而非函数被声明时的环境。也就是说声明时不知道,运行时才知道。

   this 的指向大致可以分为以下 4种:

    作为对象的方法调用。

<script type="text/javascript">
	//当函数作为对象的方法被调用时, this 指向该对象:
	var obj = {
		a:1,
		getA:function(){
			console.log(this === obj);
			console.log(this.a);
		}
	}
	obj.getA();
</script>

    作为普通函数调用。

<script>
//作为普通函数调用
	window.name = 'globalName';
	var getName = function(){
		return this.name;
	}
	console.log(getName());
	var getId = function( id ){
		return document.getElementById( id );
	};
	getId( 'div1' );
</script>

    构造器调用。

<script>
    var MyClass = function(){
        this.name = 'sven';
    };
    var obj = new MyClass();
    alert ( obj.name ); // 输出:sven
</script>        

    Function.prototype.call 或 Function.prototype.apply 调用。

<script>
    	var obj1 = {
	name: 'sven',
	getName: function(){
	return this.name;
	}
	};
	var obj2 = {
	name: 'anne'
	};
	console.log( obj1.getName() ); // 输出: sven
	console.log( obj1.getName.call( obj2 ) ); // 输出:anne
</script>

2.2  call 和 apply

  ECAMScript 3给 Function 的原型定义了两个方法,它们是 Function.prototype.call 和 Function.prototype.apply 。

2.2.1  call 和 apply 的区别

  apply 接受两个参数,第一个参数指定了函数体内 this 对象的指向,第二个参数为一个带下标的集合,这个集合可以为数组,也可以为类数组, apply 方法把这个集合中的元素作为参数传递给被调用的函数。

2.2.2  call 和 apply 的用途

  1. 改变 this 指向

<script>
	var obj1 = {
		name: 'sven'
	};
	var obj2 = {
		name: 'anne'
	};
	window.name = 'window';
	var getName = function(){
		alert ( this.name );
	};
	getName(); // 输出: window
	getName.call( obj1 ); // 输出: sven
	getName.call( obj2 ); // 输出: anne
</script>

  2.  Function.prototype.bind

	Function.prototype.bind = function(){
		var self = this,// 保存原函数
			context = [].shift.call(arguments);// 需要绑定的 this 上下文
			args = [].slice.call(arguments);// 剩余的参数转成数组
		// 返回一个新的函数
		return function(){
			// 执行新的函数的时候,会把之前传入的 context 当作新函数体内的 this
			// 并且组合两次分别传入的参数,作为新函数的参数
			return self.apply(context, [].concat.call(args, [].slice.call(arguments)));
		}
	}

	var obj1 = {
		name:'john'
	};
	var func1 = function(a,b,c,d){
		console.log(this.name);
		console.log([a,b,c,d]);
	}.bind(obj1, 1,2);

	func1(3,4);

  3. 借用其他对象的方法

    第一种场景是“借用构造函数”

//借用构造函数
	var A = functiono(name){
		this.name = name;
	}
	var B = function(){
		A.apply(this, arguments);
	}

	B.prototype.getName = function(){
		return this.name;
	}

	var b = new B('john');
	console.log(b.getName());

    第二种场景借用 Array.prototype 对象上的方法

    //借用其它对象
	(function(){
		Array.prototype.push.call(arguments, 3);
		console.log(arguments);
	})(1,2);
posted on 2018-11-07 17:09  huyanluanyu1989  阅读(167)  评论(0编辑  收藏  举报