你不知道的JavaScript之this(一)

时间:2021-09-16 13:15:04

1 this绑定和函数声明的位置没有任何关系,只取决于函数的调用位置。

2 this和词法作用域的查找混合使用时,无法实现

function foo() {
	var a=2;
	this.bar();
}
function bar() {
	console.log(this.a);
}
foo();//undefined

3 默认绑定

指向全局对象;函数直接使用不带任何修饰的函数引用进行调用的,只能使用默认绑定。

4 隐式绑定

  • 当函数引用有上下文对象时,会把函数调用的this绑定到这个上下文对象。
  • 对象属性引用链只有上一层或者说最后一层调用位置中起作用。

    function foo() {
    	console.log(this.a);
    }
    var obj2={
    	a:42,
    	foo:foo
    }
    var obj1={
    	a:2,
    	obj2:obj2
    }
    obj1.obj2.foo(); //42
  • 隐式丢失

    function foo() {
    	console.log(this.a);
    }
    var obj={
    	a:2,
    	foo:foo
    }
    var bar=obj.foo;
    var a="1";
    bar(); // 1

    bar是obj.foo的一个引用,引用的是foo函数本身,因此此时的bar()其实是一个不带任何修饰符的函数调用,因此用了默认绑定。

    回调函数

    function foo() {
    	console.log(this.a);
    }
    function doFoo(fn) {
    	fn();
    }
    var obj={
    	a:2,
    	foo:foo
    }
    var a="1";
    doFoo(obj.foo);//  1 

    参数传递其实就是一种隐式赋值,所以返回1

5 显式绑定 call()/apply()

硬绑定:

function foo() {
	console.log(this.a);
}
var obj={
	a:2,
}
var bar=function() {
	foo.call(obj);
}
bar();// 2
bar.call(window); //2  硬绑定后不能再修改它的this

创建函数bar(),并在内部调用 foo.call(obj),因此强制把foo的this绑定到obj,之后调用bar,总会手动在obj上调用foo,这种绑定称为硬绑定。

function bind(fn,obj){ //简单实现bind
	return function(){
		return fn.apply(obj,arguments);
	}
}

由于硬绑定非常常用,ES5内置提供了方法Function.prototype.bind

bind()会返回一个硬编码的新函数,会把你指定的参数设置为this的上下文并调用原始函数。

6 new绑定

new来调用函数会自动执行下面的操作

  • 创建一个新对象
  • 这个新对象会执行[[Prototype]]连接
  • 这个新对象会绑定到函数调用的this
  • 如果函数没有返回其他对象,那么new表达式中的函数调用会自动返回这个新对象