javascript this绑定机制

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_37722811/article/details/84189257

1.查找调用点:函数被调用的位置

大多数浏览器(Google)都内置开发者工具,其中就包含JS调试器。为什么要找函数的调用点?因为函数在调用点的调用形式决定了this绑定。

	function foo(something) {
            //debugger;
			console.log(this.a,something);
			return this.a + something;
		}

		var obj = {
			a: 2
		};

		var bar = function () {
			return foo.apply(obj,arguments);
		};

		var b = bar(3);

2. this绑定规则

默认绑定:独立函数调用,即函数被一个直白的,毫无修饰的函数引用调用,例如foo(), foo的this关键字被绑定到window。

隐含绑定:对象方法调用,即函数被作为对象的一个方法调用,在调用点,函数必须是对象obj的一个成员方法;例如obj.foo( ), foo的this关键字被绑定到obj。

显式绑定:调用函数的call(),apply()方法,显示的传递thisArgs,例如foo.call(obj), foo的this关键字被绑定到obj, 与隐含绑定的区别是,显示绑定的环境对象obj可以不包含这个函数foo,即两者无任何关系,只是执行时obj作为环境对象传递给函数foo使用。

构造绑定:使用new关键字调用函数,函数的this关键字被绑定到当前构造的实例。

3. 硬绑定

硬绑定是显示绑定的变种,当一个对象的方法作为参数传递给另一个函数时,隐含的绑定会丢失,当然函数执行时的this绑定取决于函数被调用的形式,我们不知道这个回调函数foo在另一个函数内部setTimeout中是如何调用的(最终的调用形式),为了防止不确定的事情发生,我们完全可以将回调函数包装成一个硬绑定函数后再传到给setTimeout。如下图:

   	function foo(){
    		console.log(this.a);
    	}
    	
    	var obj = {
    		a: 2
    	}
		
		/*
    	将foo包装成bar函数,无论如何调用和回调,都只能改包装函数bar的this绑定,内层函数foo的绑定始终不变,
    	所以我们称之为硬绑定,即明确又坚定。
    	*/
    	var bar = function() {
    		//显示绑定
    		foo.call(obj);
    	}

    	//传递包装函数bar
    	setTimeout(bar,100);

    	//使用函数表达式包装bar函数
    	setTimeout( function () { foo.call(obj)},100)

4. 箭头函数

ES6新增了箭头函数,箭头函数不仅仅是函数表达式的简写,省去了枯燥无味的function关键字,它的this绑定机制不属于以上的任何一种,它实际上采用的是词法作用域规则,箭头函数的this关键字继承外层词法作用域的this指向。后续会详细探讨,敬请期待............

猜你喜欢

转载自blog.csdn.net/m0_37722811/article/details/84189257
今日推荐