Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript “怎么说?”;这";关键词工作?_Javascript_This - Fatal编程技术网

Javascript “怎么说?”;这";关键词工作?

Javascript “怎么说?”;这";关键词工作?,javascript,this,Javascript,This,我注意到,对于什么是this关键字以及如何在堆栈溢出站点的JavaScript中正确(或错误)使用它,似乎没有一个明确的解释 我目睹了它的一些非常奇怪的行为,但我不明白为什么会发生这种情况 这个是如何工作的,什么时候应该使用它?javascript中的每个执行上下文都有一个this参数,该参数由以下参数设置: 函数的调用方式(包括作为对象方法、调用和应用的使用、新函数的使用) 绑定的使用 从词汇上讲,对于arrow函数(它们采用外部执行上下文的这种形式) 代码处于严格模式还是非严格模式 是否使用

我注意到,对于什么是
this
关键字以及如何在堆栈溢出站点的JavaScript中正确(或错误)使用它,似乎没有一个明确的解释

我目睹了它的一些非常奇怪的行为,但我不明白为什么会发生这种情况

这个
是如何工作的,什么时候应该使用它?

javascript中的每个执行上下文都有一个this参数,该参数由以下参数设置:

  • 函数的调用方式(包括作为对象方法、调用和应用的使用、新函数的使用)
  • 绑定的使用
  • 从词汇上讲,对于arrow函数(它们采用外部执行上下文的这种形式)
  • 代码处于严格模式还是非严格模式
  • 是否使用
  • 您可以使用
    func.call
    func.apply
    func.bind
    设置此值

    默认情况下,最让初学者困惑的是,当在DOM元素上引发事件后调用侦听器时,函数的this值就是DOM元素

    jQuery使得使用jQuery.proxy进行更改变得非常简单。

    是JavaScript中的一个关键字,用于获取代码执行的当前“上下文”。 它主要用于函数和构造函数

    我建议先读一读他的文章()。 这是对JavaScript中的
    this
    和作用域链概念的极好、友好的介绍。
    的规则非常简单(如果您坚持最佳实践)

    本规范中此的技术说明 通过抽象操作定义:

    抽象操作ResolveThisBinding[…]使用的词典环境确定关键字
    this
    的绑定。 调用时,它将执行以下步骤:

  • 设envRec为()
  • 返回?envRec.GetThisBinding()
  • ,并且每个都有自己的GetThisBinding方法

    抽象操作查找当前的LexicalEnvironment并查找最近的ascendant环境记录(通过迭代访问其[[OuterEnv]]属性),该记录具有this绑定(即HasThisBinding返回true)。 此过程以三种环境记录类型之一结束

    的值通常取决于代码是否在

    GetThisBinding的返回值反映了当前执行上下文的
    this
    的值,因此每当建立新的执行上下文时,
    this
    将解析为一个不同的值。 当修改当前执行上下文时也会发生这种情况。 以下小节列出了可能发生这种情况的五种情况

    您可以将代码示例与规范详细信息一起放入以遵循

    1.脚本中的全局执行上下文 这是在顶层评估的脚本代码,例如直接在
    中:

    
    //全球环境
    console.log(此);//记录全局对象。
    setTimeout(函数(){
    log(“非全局上下文”);
    });
    
    在脚本的初始全局执行上下文中,计算
    将导致采取以下步骤:

    全局环境记录envRec[…]的GetThisBinding具体方法在调用时执行以下步骤:

  • 返回envRec。[[GlobalThisValue]]
  • 全局环境记录的[[GlobalThisValue]]属性始终设置为定义的主机,可通过(
    window
    on Web,
    global
    on Node.js;)访问该主机。 按照的步骤学习[[GlobalThisValue]]属性是如何产生的

    2.中的全局执行上下文 ECMAScript 2015中引入了模块

    这适用于模块,例如直接在
    中时,而不是简单的

    在模块的初始全局执行上下文中,计算
    将导致采取以下步骤:

    模块环境记录[…]的GetThisBinding具体方法在调用时执行以下步骤:

  • 返回未定义的
  • 没错:在模块中,
    this
    的值在全局上下文中总是
    undefined

    function f1()
    {
       return this;
    }
    document.write(f1());  //[object Window]
    
    模块隐式地位于中

    3.输入代码 有两种
    eval
    调用:和。 这种区别自ECMAScript第5版以来就存在

    • 直接
      eval
      调用通常看起来像
      eval(
      (eval)(
      (或
      ((eval))(
      );
      等)1 只有当调用表达式符合一个狭窄的模式时,它才是直接的
    • 间接
      eval
      调用涉及以任何其他方式调用函数引用
      eval
      。 它可以是
      eval?(
      ,eval)(
      window.eval(
      eval.call(
      )等等。 给定
      常量别名eval1=eval;window.aliasEval2=eval,它也将是
      aliasEval1(
      aliasEval2(
      。 分别给出
      const originalEval=eval;window.eval=(x)=>originalEval(x)
      ,调用
      eval(
      也是间接的
    有关何时可以使用间接
    eval()调用的信息,请参见和()

    执行
    eval
    代码。 它创建了一个新的as-LexicalEnvironment,从中获取
    this

    然后,如果在
    eval
    code中出现
    this
    ,则调用找到的环境记录的GetThisBinding方法并返回其值

    创建的调用取决于
    eval
    调用是直接调用还是间接调用:

    • 在直接评估中,它将基于当前的词汇环境。
    • document.write(this); //[object Window]
    function f1()
    {
       return this;
    }
    document.write(f1());  //[object Window]
    
    function f()
    {
        return this;
    }
    
    document.write(window.f()); //[object Window]
    
    var obj = {
        name: "obj",
        f: function () {
            return this + ":" + this.name;
        }
    };
    document.write(obj.f());  //[object Object]:obj
    
    var obj = {
        name: "obj1",
        nestedobj: {
            name:"nestedobj",
            f: function () {
                return this + ":" + this.name;
            }
        }            
    }
    
    document.write(obj.nestedobj.f()); //[object Object]:nestedobj
    
    var obj1 = {
        name: "obj1",
    }
    
    function returnName() {
        return this + ":" + this.name;
    }
    
    obj1.f = returnName; //add method to object
    document.write(obj1.f()); //[object Object]:obj1
    
    var context = "global";
    
    var obj = {  
        context: "object",
        method: function () {                  
            function f() {
                var context = "function";
                return this + ":" +this.context; 
            };
            return f(); //invoked without context
        }
    };
    
    document.write(obj.method()); //[object Window]:global 
    
    /********************************************************************* 
      1. When you add variable to the function using this keyword, it 
         gets added to the function prototype, thus allowing all function 
         instances to have their own copy of the variables added.
    *********************************************************************/
    function functionDef()
    {
        this.name = "ObjDefinition";
        this.getName = function(){                
            return this+":"+this.name;
        }
    }        
    
    obj1 = new functionDef();
    document.write(obj1.getName() + "<br />"); //[object Object]:ObjDefinition   
    
    /********************************************************************* 
       2. Members explicitly added to the function protorype also behave 
          as above: all function instances have their own copy of the 
          variable added.
    *********************************************************************/
    functionDef.prototype.version = 1;
    functionDef.prototype.getVersion = function(){
        return "v"+this.version; //see how this.version refers to the
                                 //version variable added through 
                                 //prototype
    }
    document.write(obj1.getVersion() + "<br />"); //v1
    
    /********************************************************************* 
       3. Illustrating that the function variables added by both above 
          ways have their own copies across function instances
    *********************************************************************/
    functionDef.prototype.incrementVersion = function(){
        this.version = this.version + 1;
    }
    var obj2 = new functionDef();
    document.write(obj2.getVersion() + "<br />"); //v1
    
    obj2.incrementVersion();      //incrementing version in obj2
                                  //does not affect obj1 version
    
    document.write(obj2.getVersion() + "<br />"); //v2
    document.write(obj1.getVersion() + "<br />"); //v1
    
    /********************************************************************* 
       4. `this` keyword refers to the immediate parent object. If you 
           nest the object through function prototype, then `this` inside 
           object refers to the nested object not the function instance
    *********************************************************************/
    functionDef.prototype.nestedObj = { name: 'nestedObj', 
                                        getName1 : function(){
                                            return this+":"+this.name;
                                        }                            
                                      };
    
    document.write(obj2.nestedObj.getName1() + "<br />"); //[object Object]:nestedObj
    
    /********************************************************************* 
       5. If the method is on an object's prototype chain, `this` refers 
          to the object the method was called on, as if the method was on 
          the object.
    *********************************************************************/
    var ProtoObj = { fun: function () { return this.a } };
    var obj3 = Object.create(ProtoObj); //creating an object setting ProtoObj
                                        //as its prototype
    obj3.a = 999;                       //adding instance member to obj3
    document.write(obj3.fun()+"<br />");//999
                                        //calling obj3.fun() makes 
                                        //ProtoObj.fun() to access obj3.a as 
                                        //if fun() is defined on obj3
    
    var myname = "global context";
    function SimpleFun()
    {
        this.myname = "simple function";
    }
    
    var obj1 = new SimpleFun(); //adds myname to obj1
    //1. `new` causes `this` inside the SimpleFun() to point to the
    //   object being constructed thus adding any member
    //   created inside SimipleFun() using this.membername to the
    //   object being constructed
    //2. And by default `new` makes function to return newly 
    //   constructed object if no explicit return value is specified
    
    document.write(obj1.myname); //simple function
    
    var ProtoObj = {
        fun: function () {
            return this.a;
        }
    };
    //Object.create() creates object with ProtoObj as its
    //prototype and assigns it to obj3, thus making fun() 
    //to be the method on its prototype chain
    
    var obj3 = Object.create(ProtoObj);
    obj3.a = 999;
    document.write(obj3.fun()); //999
    
    //Notice that fun() is defined on obj3's prototype but 
    //`this.a` inside fun() retrieves obj3.a   
    
    function add(inc1, inc2)
    {
        return this.a + inc1 + inc2;
    }
    
    var o = { a : 4 };
    document.write(add.call(o, 5, 6)+"<br />"); //15
          //above add.call(o,5,6) sets `this` inside
          //add() to `o` and calls add() resulting:
          // this.a + inc1 + inc2 = 
          // `o.a` i.e. 4 + 5 + 6 = 15
    document.write(add.apply(o, [5, 6]) + "<br />"); //15
          // `o.a` i.e. 4 + 5 + 6 = 15
    
    var g = add.bind(o, 5, 6);       //g: `o.a` i.e. 4 + 5 + 6
    document.write(g()+"<br />");    //15
    
    var h = add.bind(o, 5);          //h: `o.a` i.e. 4 + 5 + ?
    document.write(h(6) + "<br />"); //15
          // 4 + 5 + 6 = 15
    document.write(h() + "<br />");  //NaN
          //no parameter is passed to h()
          //thus inc2 inside add() is `undefined`
          //4 + 5 + undefined = NaN</code>
    
    <script> 
        function clickedMe() {
           alert(this + " : " + this.tagName + " : " + this.id);
        } 
        document.getElementById("button1").addEventListener("click", clickedMe, false);
        document.getElementById("button2").onclick = clickedMe;
        document.getElementById("button5").attachEvent('onclick', clickedMe);   
    </script>
    
    <h3>Using `this` "directly" inside event handler or event property</h3>
    <button id="button1">click() "assigned" using addEventListner() </button><br />
    <button id="button2">click() "assigned" using click() </button><br />
    <button id="button3" onclick="alert(this+ ' : ' + this.tagName + ' : ' + this.id);">used `this` directly in click event property</button>
    
    <h3>Using `this` "indirectly" inside event handler or event property</h3>
    <button onclick="alert((function(){return this + ' : ' + this.tagName + ' : ' + this.id;})());">`this` used indirectly, inside function <br /> defined & called inside event property</button><br />
    
    <button id="button4" onclick="clickedMe()">`this` used indirectly, inside function <br /> called inside event property</button> <br />
    
    IE only: <button id="button5">click() "attached" using attachEvent() </button>
    
    (function(){}).bind(this)
    
    function someKindOfFunction() {
       this.style = 'foo';
    }
    
    var val = "window.val"
    
    var obj = {
        val: "obj.val",
        innerMethod: function () {
            var val = "obj.val.inner",
                func = function () {
                    var self = this;
                    return self.val;
                };
    
            return func;
        },
        outerMethod: function(){
            return this.val;
        }
    };
    
    //This actually gets executed inside window object 
    console.log(obj.innerMethod()()); //returns window.val
    
    //Breakdown in to 2 lines explains this in detail
    var _inn = obj.innerMethod();
    console.log(_inn()); //returns window.val
    
    console.log(obj.outerMethod()); //returns obj.val
    
    var status = 1;
    var helper = {
        status : 2,
        getStatus: function () {
            return this.status;
        }
    };
    
    var theStatus1 = helper.getStatus(); //line1
    console.log(theStatus1); //2
    
    var theStatus2 = helper.getStatus;
    console.log(theStatus2()); //1
    
    function Person(name){
        this.personName = name;
        this.sayHello = function(){
            return "Hello " + this.personName;
        }
    }
    
    var person1 = new Person('Scott');
    console.log(person1.sayHello()); //Hello Scott
    
    var person2 = new Person('Hugh');
    var sayHelloP2 = person2.sayHello;
    console.log(sayHelloP2()); //Hello undefined
    
    function testFunc() {
        this.name = "Name";
        this.myCustomAttribute = "Custom Attribute";
        return this;
    }
    
    var whatIsThis = testFunc();
    console.log(whatIsThis); //window
    
    var whatIsThis2 = new testFunc();
    console.log(whatIsThis2);  //testFunc() / object
    
    console.log(window.myCustomAttribute); //Custom Attribute 
    
    <script type="application/javascript">
        function click_handler() {
            alert(this); // alerts the window object
        }
    </script>
    
    <button id='thebutton' onclick='click_handler()'>Click me!</button>
    
    function foo() {
        console.log("bar");
        console.log(this);
    }
    foo(); // calling the function
    
    var myObj = {key: "Obj"};
    myObj.logThis = function () {
        // I am a method
        console.log(this);
    }
    myObj.logThis(); // myObj is logged
    
    // continuing with the previous code snippet
    
    var myVar = myObj.logThis;
    myVar();
    // logs either of window/global/undefined based on mode of operation
    
    var el = document.getElementById('idOfEl');
    el.addEventListener('click', function() { console.log(this) });
    // the function called by addEventListener contains this as the reference to the element
    // so clicking on our element would log that element itself
    
    function Person (name) {
        this.name = name;
        this.sayHello = function () {
            console.log ("Hello", this);
        }
    }
    
    var awal = new Person("Awal");
    awal.sayHello();
    // In `awal.sayHello`, `this` contains the reference to the variable `awal`
    
    function foo () { console.log (this, arguments); }
    var thisArg = {myObj: "is cool"};
    foo.call(thisArg, 1, 2, 3);
    
    foo.apply(thisArg, [1,2,3])
    
    function foo (a, b) {
        console.log (this, arguments);
    }
    var thisArg = {myObj: "even more cool now"};
    var bound = foo.bind(thisArg, 1, 2);
    console.log (typeof bound); // logs `function`
    console.log (bound);
    /* logs `function () { native code }` */
    
    bound(); // calling the function returned by `.bind`
    // logs `{myObj: "even more cool now"}, [1, 2]`
    
    var myObj = {
        hello: function () {
            return "world"
            },
        myMethod: function () {
            // copy this, variable names are case-sensitive
            var that = this;
            // callbacks ftw \o/
            foo.bar("args", function () {
                // I want to call `hello` here
                this.hello(); // error
                // but `this` references to `foo` damn!
                // oh wait we have a backup \o/
                that.hello(); // "world"
            });
        }
      };
    
    var person = {    
        firstName: "Penelope",
        lastName: "Barrymore",
        fullName: function () {
    
        // We use "this" just as in the sentence above:
           console.log(this.firstName + " " + this.lastName);
    
        // We could have also written:
           console.log(person.firstName + " " + person.lastName);
        }
    }
    
    function foo() {
         // return an arrow function
         return (a) => {
         // `this` here is lexically inherited from `foo()`
         console.log(this.a);
      };
    }
    var obj1 = { a: 2 };
    var obj2 = { a: 3 };
    
    var bar = foo.call(obj1);
    bar.call( obj2 ); // 2, not 3!
    
    <script type="text/javascript">
      console.log(this === window); // true
      var foo = "bar";
      console.log(this.foo); // "bar"
      console.log(window.foo); // "bar"
    
    >this
      { ArrayBuffer: [Function: ArrayBuffer],
        Int8Array: { [Function: Int8Array] BYTES_PER_ELEMENT: 1 },
        Uint8Array: { [Function: Uint8Array] BYTES_PER_ELEMENT: 1 },
        ...
    >global === this
     true
    
    \\test.js
    console.log(this);  \\ {}
    console.log(this === global); \\ fasle
    
    <script type="text/javascript">
        foo = "bar";
    
        function testThis() {
          this.foo = "foo";
        }
    
        console.log(this.foo); //logs "bar"
        testThis();
        console.log(this.foo); //logs "foo"
    </script>
    
    <script type="text/javascript">
        foo = "bar";
    
        function testThis() {
          "use strict";
          this.foo = "foo";
        }
    
        console.log(this.foo); //logs "bar"
        testThis();  //Uncaught TypeError: Cannot set property 'foo' of undefined 
    </script>
    
    <script type="text/javascript">
        foo = "bar";
    
        function testThis() {
          this.foo = "foo";
        }
    
        console.log(this.foo); //logs "bar"
        new testThis();
        console.log(this.foo); //logs "bar"
    
        console.log(new testThis().foo); //logs "foo"
    </script>
    
    function Thing() {
      console.log(this.foo);
    }
    
    Thing.prototype.foo = "bar";
    
    var thing = new Thing(); //logs "bar"
    console.log(thing.foo);  //logs "bar"
    
    function Thing() {
        this.things = [];
    }
    
    var thing1 = new Thing();
    var thing2 = new Thing();
    thing1.things.push("foo");
    console.log(thing1.things); //logs ["foo"]
    console.log(thing2.things); //logs []
    
    var obj = {
        foo: "bar",
        logFoo: function () {
            console.log(this.foo);
        }
    };
    
    obj.logFoo(); //logs "bar"
    
    function Listener() {
        document.getElementById("foo").addEventListener("click",
           this.handleClick);
    }
    Listener.prototype.handleClick = function (event) {
        console.log(this); //logs "<div id="foo"></div>"
    }
    
    var listener = new Listener();
    document.getElementById("foo").click();
    
    function Listener() {
        document.getElementById("foo").addEventListener("click", 
            this.handleClick.bind(this));
    }
    Listener.prototype.handleClick = function (event) {
        console.log(this); //logs Listener {handleClick: function}
    }
    
    var listener = new Listener();
    document.getElementById("foo").click();
    
    <div id="foo" onclick="console.log(this);"></div>
    <script type="text/javascript">
    document.getElementById("foo").click(); //logs <div id="foo"...
    </script>
    
    function Thing () {
    }
    Thing.prototype.foo = "bar";
    Thing.prototype.logFoo = function () {
        eval("console.log(this.foo)"); //logs "bar"
    }
    
    var thing = new Thing();
    thing.logFoo();
    
    function Thing () {
    }
    Thing.prototype.foo = "bar";
    Thing.prototype.logFoo = function () {
        with (this) {
            console.log(foo);
            foo = "foo";
        }
    }
    
    var thing = new Thing();
    thing.logFoo(); // logs "bar"
    console.log(thing.foo); // logs "foo"
    
    <div class="foo bar1"></div>
    <div class="foo bar2"></div>
    <script type="text/javascript">
    $(".foo").each(function () {
        console.log(this); //logs <div class="foo...
    });
    $(".foo").on("click", function () {
        console.log(this); //logs <div class="foo...
    });
    $(".foo").each(function () {
        this.click();
    });
    </script>
    
      <script type="text/javascript" language="javascript">
    $('#tbleName tbody tr').each(function{
    var txt='';
    txt += $(this).find("td").eq(0).text();
    \\same as above but synatx different
    var txt1='';
     txt1+=$('#tbleName tbody tr').eq(0).text();
    alert(txt1)
    });
    </script>
    
    function UserDefinedFunction(){
        alert(this)
        }
    
    window.UserDefinedFunction=function(){
      alert(this)
    }  
    
    UserDefinedFunction() // displays [object Window]  as it automatically gets invoked as window.UserDefinedFunction()
    
    UserDefinedFunction() // displays undefined
    
    window.UserDefinedFunction() // "always displays [object Window]   irrespective of mode."
    
     function UserDefinedFunction()
        {
            alert(this.a + ","  + this.b + ","  + this.c  + ","  + this.d)
        }
    
    var o1={
                a:1,
                b:2,
                f:UserDefinedFunction
          }
    var o2={
                c:3,
                d:4,
                f:UserDefinedFunction
           }
    
    o1.f() // Shall display 1,2,undefined,undefined
    o2.f() // Shall display undefined,undefined,3,4
    
    function UserDefinedFunction()
    {
        alert(this.a + ","  + this.b + ","  + this.c  + ","  + this.d)
    }
    var o1={
                a:1,
                b:2,
                f:UserDefinedFunction
           }
    var o2={
                c:3,
                d:4,
                f:UserDefinedFunction
           }
    
    UserDefinedFunction.call(o1) // Shall display 1,2,undefined,undefined
    UserDefinedFunction.apply(o1) // Shall display 1,2,undefined,undefined
    
    UserDefinedFunction.call(o2) // Shall display undefined,undefined,3,4
    UserDefinedFunction.apply(o2) // Shall display undefined,undefined,3,4
    
    o1.f.call(o2) // Shall display undefined,undefined,3,4
    o1.f.apply(o2) // Shall display undefined,undefined,3,4
    
    o2.f.call(o1) // Shall display 1,2,undefined,undefined
    o2.f.apply(o1) // Shall display 1,2,undefined,undefined
    
    function UserDefinedFunction()
    {
        alert(this.a + ","  + this.b + ","  + this.c  + ","  + this.d)
    }
    var o1={
              a:1,
              b:2,
              f:UserDefinedFunction,
              bf:null
           }
    var o2={
               c:3,
               d:4,
               f:UserDefinedFunction,
               bf:null
            }
    
    var bound1=UserDefinedFunction.bind(o1); // permanantly fixes "this" value of function "bound1" to Object o1
    bound1() // Shall display 1,2,undefined,undefined
    
    var bound2=UserDefinedFunction.bind(o2); // permanantly fixes "this" value of function "bound2" to Object o2
    bound2() // Shall display undefined,undefined,3,4
    
    var bound3=o1.f.bind(o2); // permanantly fixes "this" value of function "bound3" to Object o2
    bound3() // Shall display undefined,undefined,3,4
    
    var bound4=o2.f.bind(o1); // permanantly fixes "this" value of function "bound4" to Object o1
    bound4() // Shall display 1,2,undefined,undefined
    
    o1.bf=UserDefinedFunction.bind(o2) // permanantly fixes "this" value of function "o1.bf" to Object o2
    o1.bf() // Shall display undefined,undefined,3,4
    
    o2.bf=UserDefinedFunction.bind(o1) // permanantly fixes "this" value of function "o2.bf" to Object o1
    o2.bf() // Shall display 1,2,undefined,undefined
    
    bound1.call(o2) // Shall still display 1,2,undefined,undefined. "call" cannot alter the value of "this" for bound function
    
    bound1.apply(o2) // Shall still display 1,2,undefined,undefined. "apply" cannot alter the value of "this" for bound function
    
    o2.bf.call(o2) // Shall still display 1,2,undefined,undefined. "call" cannot alter the value of "this" for bound function
    o2.bf.apply(o2) // Shall still display 1,2,undefined,undefined."apply" cannot alter the value of "this" for bound function
    
    <button onclick='this.style.color=white'>Hello World</button>
    <div style='width:100px;height:100px;' onclick='OnDivClick(event,this)'>Hello World</div>
    
    function Car(make, model, year) {
    var this = {}; // under the hood, so to speak
    this.make = make;
    this.model = model;
    this.year = year;
    return this; // under the hood
    }
    
    var mycar = new Car('Eagle', 'Talon TSi', 1993);
    // ========= under the hood
    var this = {};
    this.make = 'Eagle';
    this.model = 'Talon TSi';
    this.year = 1993;
    return this;
    
    console.log(this)
    
    console.log(this === window) // true
    
    console.log(this === module.exports) // true
    console.log(this === exports) // true
    
    functionObject.call(objectForThis, arg0, arg1, arg2, ...);
    
        <script>
            console.log('What is this: '+this);
            console.log(this);
        </script>
    
        <script>
            function myFunc(){
                console.log('What is this: '+this);
                console.log(this);
            }
            myFunc();
        </script>
    
     <script>
            var firstName = "Nora";
            var lastName = "Zaman";
            var myObj = {
                firstName:"Lord",
                lastName:'Baron',
                printNameGetContext:function(){
                    console.log(firstName + " "+lastName);
                    console.log(this.firstName +" "+this.lastName);
                    return this;
                }
            }
    
          var context = myObj.printNameGetContext();
          console.log(context);
        </script>
    
    <body>
        <button class="btn">Click Me</button>
        <script>
            function printMe(){
                //Terminal2: this function declared inside window context so this function belongs to the window object.
                console.log(this);
            }
            document.querySelector('.btn').addEventListener('click', function(){
                //Terminal1: button context, this callback function belongs to DOM element 
                console.log(this);
                printMe();
            })
        </script>
    </body>
    
    <script>
            var myObj = {
                firstName:"Lord",
                lastName:'Baron',
                printName:function(callback1, callback2){
                    //Attaching callback1 with this myObj context
                    this.callback1 = callback1;
                    this.callback1(this.firstName +" "+this.lastName)
                    //We did not attached callback2 with myObj so, it's reamin with window context by default
                    callback2();
                    /*
                     //test bellow codes
                     this.callback2 = callback2;
                     this.callback2();
                    */
                }
            }
            var callback2 = function (){
                console.log(this);
            }
            myObj.printName(function(data){
                console.log(data);
                console.log(this);
            }, callback2);
        </script>
    
           var color = 'red'; // property of window
           var obj = {
               color:'blue', // property of window
               printColor: function(){ // property of obj, attached with obj
                   var self = this;
                   console.log('In printColor -- this.color: '+this.color);
                   console.log('In printColor -- self.color: '+self.color);
                   (function(){ // decleard inside of printColor but not property of object, it will executed on window context.
                        console.log(this)
                        console.log('In IIFE -- this.color: '+this.color);
                        console.log('In IIFE -- self.color: '+self.color); 
                   })();
    
                   function nestedFunc(){// decleard inside of printColor but not property of object, it will executed on window context.
                        console.log('nested fun -- this.color: '+this.color);
                        console.log('nested fun -- self.color: '+self.color);
                   }
    
                   nestedFunc(); // executed on window context
                   return nestedFunc;
               }
           };
    
           obj.printColor()(); // returned function executed on window context
       </script>