记录学习--关于this。第一天

155 阅读1分钟

1.调用位置

在this绑定过程之前,先要知道this的调用地方在哪,也就是说函数在代码中被调用的位置,(不是声明位置)。
关于调用位置的例子:

function fn(){
    //当前调用是:fn
    //因此,当前调用位置是全局作用域
    console.log("fn")
    fn1() // <--fn1调用的位置
}

function fn1(){
    //当前调用栈是 fn—>fn1
    //当前调用位置在 fn中
    console.log("fn1")
    fn2(); // fn2的调用位置
}
function fn2(){
    //当前调用栈是 fn->fn1->fn2
    //当前调用位置在fn1中
    console.log("fn2")
}
fn() // <--fn的调用位置

你可以把调用栈想象成一个函数调用链,就像我们在前面代码段的注释中所写的一样。

2.绑定规则

据我目前所学到的来看,目前学到了四条绑定规则,分别是默认绑定、隐式绑定、 显式绑定、new绑定。

2.1默认绑定
function foo(){
   console.log(this.a);
}
var a = 2;
foo(); //2

在代码中,foo()是直接使用不带任何修饰的函数引用进行调用的,因此只能使用默认绑定,无法应用其他规则。 如果使用严格模式(strict mode),则不能将全局对象用于默认绑定,因此this会绑定到undefined:


function foo(){
    "user strict";
   console.log(this.a);
}
var a = 2;
foo(); // TypeError:this is undefined
2.2隐式绑定
function foo(){
   console.log(this.a);
}
var obj = {
    a:2,
    foo
};
obj.foo(); //2

首先需要注意的是foo()的声明方式,及其之后是如何被当作引用属性添加到obj中的。但是无论是直接在obj中定义还是先定义再添加为引用属性,这个函数严格来说都不属于obj对象
然而,调用位置会使用obj上下文来引用函数,因此你可以说函数被调用时obj对象“拥有”或者“包含”它。
对象属性引用链中只有上一层或者说最后一层在调用位置中起作用。举例来说:

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

一个最常见的this绑定问题就是被隐式绑定的函数会丢失绑定对象,也就是说它会应用默认绑定,从而把this绑定到全局对象或者undefined上,取决于是否是严格模式。

function foo(){
    console.log(this.a) ;
}

var obj = {
    a: 2,
    foo: foo
    };
    
var bar = obj.foo;/函数别名!
var a ="global";  // a是全局对象的属性
bar(); //"global"
2.3显式绑定

JavaScript提供的绝大多数函数以及你自己创建的所有函数都可以使用call(..)和apply(..)方法。

function foo(){
    console. log(this. a);
}

var obj = {
    a: 2
};

foo.call(obj);// 2

还有其他用法,目前我接触的也基本就这么多,欢迎各位大佬来补充,扩充我的知识点。