js中的this

1、什么是this?

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

1.1调用位置

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>

</body>
<script type="text/javascript">
    function baz(){
        //调用栈 :baz
        console.log("baz")
        bar(); //bar的调用位置
    }
    function bar(){
        // 当前调用栈 baz --> bar
        console.log("bar");
        foo(); //foo的调用位置
    }
    function foo(){
        // 当前调用栈 baz --> bar -->foo
        console.log("foo");

    }
    baz(); //baz的调用位置
</script>
</html>

2、绑定规则

2.1 默认绑定

不带任何修饰的函数引用调用,只能默认绑定。在非严格模式下,默认绑定才能绑定到全局对象。

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>

</body>
<script type="text/javascript">
    function foo(){
        // "use strict"; 使用严格模式会报错
        var a =1
        console.log(this.a) //2
    }
    var a =2;
    foo();
</script>
</html>

foo运行在非严格模式下,默认绑定到全局

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>

</body>
<script type="text/javascript">
    function bar(){
        "user strict";
        foo();
    }
    function foo(){
        // foo运行在非严格模式下,默认绑定到全局
        // 严格模式和非严格模式不应该混用
        console.log(a) // 1
    }
    var a =1;
    bar();
</script>
</html>

2.2 隐式绑定、

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>

</body>
<script type="text/javascript">
    function foo(){
        console.log(this.a) //2
    }
    var obj={
        a:2,
        foo:foo,
    }
    var a = 100;
    obj.foo();
</script>
</html>

隐式绑定规则会把foo这个函数调用中的this绑定到obj的上下文对象中,此时this.a === obj.a

2.2.1隐性绑定丢失

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>

</body>
<script type="text/javascript">
    function foo(){
        console.log(this.a) //100
    }
    var obj={
        a:2,
        foo:foo,
    }
    var a = 100;
    var baz = obj.foo;
    baz();
</script>
</html>
<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>

</body>
<script type="text/javascript">
    function foo(){
        console.log(this.a) //100
    }
    var obj={
        a:2,
        foo:foo,
    }
    var a = 100;
    function baz(fn){
        fn(); //foo调用位置
    }
    baz(obj.foo);
</script>
</html>

2.3显示绑定

2.3.1 硬绑定

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>

</body>
<script type="text/javascript">
    function foo(){
        console.log(this.a); //2
    }
    var obj = {
        a:2,
    };
    var a = 100;
    var bar = function(){
        foo.call(obj);
    }
    bar();
    bar.call(window) //2 硬绑定不可能在修改它的this
</script>
</html>

2.3.2new绑定

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>

</body>
<script type="text/javascript">
    function foo(a){
        this.a =a
    }

    var bar = new foo(2)
    console.log(bar.a); //2
</script>
</html>

 2.4 优先级

2.4.1 显示绑定比隐式绑定优先级高

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>

</body>
<script type="text/javascript">
    function foo(){
        console.log(this.a);
    }
    var obj1 ={
        a:2,
        foo:foo,
    }
    var obj2 ={
        a:3,
        foo:foo,
    }
    obj1.foo(); //2
    obj2.foo(); //3
    obj1.foo.call(obj2); //3
    obj2.foo.call(obj1); //2
</script>
</html>

2.4.2 new绑定优先级比隐式绑定优先级高

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>

</body>
<script type="text/javascript">
    function foo(a){
        this.a = a;
    }
    var obj1 = {
        foo:foo,
    }
    var obj2 ={};
    obj1.foo(2); 
    console.log(obj1.a); // 2
    obj1.foo.call(obj2, 3);
    console.log(obj2.a); //3
    var bar = new obj1.foo(4);
    console.log(obj1.a) //2
    console.log(bar.a) // 4
</script>
</html>

2.5 总结

1、函数是否在new中调用(new绑定)?如果是,this绑定的是新创建的对象。

var bar= new foo();

2、函数是否通过call,apply(显示绑定)或者硬绑定调用?如果是,this绑定的是指定对象

var bar = foo.call(obj1)

3、函数是否在某个上下文对象中调用(隐式绑定)?如果是,this绑定的是绑定的那个上下文对象。

4、如果都不是,使用默认绑定,严格模式下绑定到undefined,否则绑定到全局对象。

posted @ 2018-07-09 19:25  Jason_lincoln  阅读(121)  评论(0编辑  收藏  举报