zoukankan      html  css  js  c++  java
  • 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,否则绑定到全局对象。

  • 相关阅读:
    ES6 Promise用法讲解
    NPM使用介绍
    Docker学习系列(二):Docker三十分钟快速入门(上)
    Spring Cloud学习(一)
    胖ap和瘦ap的区别
    论网络知识的重要性
    2018 发发发发
    sikuli--前端自动化操作的神器
    更改MySQL数据库的编码为utf8mb4
    数据库mysql的常规操作
  • 原文地址:https://www.cnblogs.com/Jason-lin/p/9285581.html
Copyright © 2011-2022 走看看