zoukankan      html  css  js  c++  java
  • javascript中的this值

    如何确定this的值 

    this值会被传递给所有函数,this的值是基于运行时调用函数的上下文。

    例如:从全局作用域调用sayFoo函数时,this引用window对象, 当它作为myObject的一种方法调用时,this引用myObject

            var foo = "foo";
            var myObject = { foo: "I am myObject.foo" };
    
            var sayFoo = function () {
                console.log(this.foo);
            };
    
            //给myObject设置一个sayFoo属性,并指向sayFoo函数
            myObject.sayFoo = sayFoo;
            myObject.sayFoo();//输出 I am myObject.foo
            sayFoo(); //输出foo

    在嵌套函数中用this关键字引用head对象

    当在嵌套函数内部使用this时,在ES3中,this失去了方向,引用的是head对象

    例如:func2和func3内部的this失去了方向,引用的不是myObject,而是head对象

    var myObject = {
                
                func1: function() {
                    console.log(this); //输出myObject
    
                    var func2 = function() {
                        console.log(this); //输出window,从此处开始,this都是window对象了
    
                        var func3 = function () {
                            console.log(this);//输出window,即head对象
                        }();
                    }();
                }
            };
            myObject.func1();

    当匿名函数在函数内部被调用时,匿名函数内的this值将是head对象。例如:

    var foo = {
                func1: function(bar) {
                    bar(); //输出window,而不是foo
                    console.log(this); //这里的this关键字是foo对象的一个引用
                }
            };        
            foo.func1(function() {
                console.log(this);
            });

    当this值得宿主函数被封装在另外一个函数内部或在另一个函数的上下文中被调用时,this值将永远是对head对象的引用。

    充分利用作用域链研究嵌套函数问题

    可以简单的在父函数中使用作用域链来保留对this的引用,以便this值不丢失。如下代码演示通过 that变量以及其作用域来有效的跟踪函数上下文:

     //充分利用作用域链研究嵌套函数问题 
            var myObject = {
                myProperty:"I can see the light",
                myMethod: function() {
                    var that = this; //myMethod作用域内,保存this引用(也就是myObject)
                    var helperFunction = function() { //子函数 
                        //输出通过作用域链得到“I can see the light”
                        console.log(that.myProperty);
                        console.log(this.myProperty);
                        console.log(this);
                    }();
                }
            };
            myObject.myMethod();//调用myMethod

    使用call()或apply()控制this值

    this值通常取决于调用函数的上下文,但是我们可以使用apply()或call()来重写/控制this值

    call()和apply()的区别在于函数传递参数的方式不同

    如果使用call(),参数只是用逗号分隔的值

    如果使用apply(),参数值以数组的形式传递。 

    例如如下:通过 call调用函数,以便使函数内部的this值将myObject作为它的上下文

    //使用call()或apply()控制this值
            var myObject = {};
            var myFunction = function(parm1, parm2) {
                //调用函数的时候,通过call()将this指向myObject
                this.foo = parm1;
                this.bar = parm2;
                console.log(this);
            };
             myFunction.call(myObject, "foo", "bar");//调用函数,设置this值引用到myObject
             console.log("foo=" + myObject.foo + ",bar=" + myObject.bar); //输foo=foo,bar=bar

    改为直接调用的结果为:

           var myObject = {};
            var myFunction = function(parm1, parm2) {
                //调用函数的时候,通过call()将this指向myObject
                this.foo = parm1;
                this.bar = parm2;
                console.log(this);
            };
            myFunction("foo", "bar");//直接调用,this指向window
            console.log("foo=" + myObject.foo + ",bar=" + myObject.bar);//foo=undefined,bar=undefined
            console.log("foo=" + myFunction.foo + ",bar=" + myFunction.bar);//foo=undefined,bar=undefined
            console.log("foo=" + foo + ",bar=" + bar);//foo=foo,bar=bar

    在用户自定义构造函数内部使用this关键字

    使用new关键字调用函数时,this值(在构造函数中声明的)引用实例本身。

    例如:如下代码创建了Person构造函数,创建Person的实例时,this.name将引用新创建的对象。

           var Person = function(name) {
                this.name = name || "john doe";//this引用所创建的实例
            };
    
            var cody = new Person("Cody Lindley");//基于Person构造函数创建实例
            console.log(cody.name);//输出Cody Lindley

    使用new关键字调用构造函数时,this引用“即将创建的对象”

    如果不使用new关键字,this值将是调用Person的上下文—在本例中是head对象。如下代码:

            var Person2 = function (name) {
                this.name = name || "john doe"; //this引用所创建的实例
            };
    
            var cody2 = Person2("Cody Lindley"); //基于Person构造函数创建实例
           console.log(cody2.name); //报name不存在,实际上name值设置到了window.name上
           console.log(window.name); //输出Cody Lindley

    原型方法内的this关键字引用构造函数实例

    当在添加至构造函数的prototype属性的函数中使用this时,this引用调用方法的实例,例如:

           //原型方法内的this关键字引用构造函数实例
            var Person = function(x) {
                if (x) {
                    this.fullName = x;
                }
            };
    
            Person.prototype.whatIsMyName = function() {
                return this.fullName;//this引用Person()所创建的实例上
            };
    
            var cody = new Person("cody lindley");
            var lisa = new Person("lisa lindley");
    
            //调用继承的whatIsMyName方法,该方法用this引用实例
            console.log(cody.whatIsMyName(), lisa.whatIsMyName()); //输出cody lindley,lisa lindley
    
            Object.prototype.fullName = "John Doe";
            var john = new Person();
            console.log(john.whatIsMyName());

    当在prototype对象中的方法内部使用this关键字时,this可用于引用实例。如果该实例不包含所要查找的属性,则继续在原型上查找。

  • 相关阅读:
    CentOS7 下部署 Iptables 环境纪录(关闭默认的firewalle)
    Linux系统下root密码遗忘等系统故障的修复方法
    LDAP学习笔记总结
    kvm虚拟化关闭虚拟网卡virbr0的方法
    Gradle使用指南
    Android 注解工具 ButterKnife
    Sublime Text + CTags + Cscope (部分替代Source Insight)
    win + linux + android 多任务分屏
    Ubuntu16.04 安装openjdk-7-jdk
    eclipse + Android Studio 集成 Genymotion 模拟器
  • 原文地址:https://www.cnblogs.com/alice626/p/4956146.html
Copyright © 2011-2022 走看看