美文网首页
关于js 中的this

关于js 中的this

作者: aibinMr | 来源:发表于2019-07-24 23:13 被阅读0次
            var name='小张',
            age=17;
            var obj={
                name:'小刘',
                objAge:this.age,
                myFun:function(){
                    console.log(this.name+'年龄'+this.age);
                    console.log('查看对象内'+this.objAge)
                }
            }
            obj.myFun()
            //小刘年龄undefined
            //查看对象内17
            var db={
                name:'德玛',
                age:99
            }
            var db2={
                name:'伽罗',
            }
            obj.myFun();
            obj.myFun.call();//小张年龄17 此时this指向window
            obj.myFun.call(db);//德玛年龄99
            obj.myFun.call(db2);//伽罗年龄undefined 说明传入对象替换了this,
            obj.myFun.apply(db);//德玛年龄99
            obj.myFun.bind(db)();//德玛年龄99---->bind 返回的是函数,必需调用执行
            var obj2={
                name:'小刘',
                objAge:this.age,
                myFun:function(fm,t){
                    console.log(this.name+'年龄'+this.age,'来自'+fm+'去往'+t);
                }
            }
            //call、 bind、 apply 这三个函数的第一个参数都是this的指向对象
            //|->call可以传入多个参数,多个参数逗号隔开
            obj2.myFun.call(db,'江西','深圳');//德玛年龄99 来自江西去往深圳
            //|->apply只能传入两个参数,所以其第二个参数往往是作为数组形式传入
            obj2.myFun.apply(db,['江西','深圳']);//德玛年龄99 来自江西去往深圳
            //|->bind除了返回函数以外,它的参数和call 一样
            obj2.myFun.bind(db,'江西','深圳')();//德玛年龄99 来自江西去往深圳
            //|->此处测试是吧'江西,深圳'作为一个数组传进去,所以参数fm就是'江西,深圳',中间的逗号应该是数组转义的时候产生的
            obj2.myFun.bind(db,['江西','深圳'])();//德玛年龄99 来自江西,深圳去往undefined
    
            function fun1() {
                this.ccfun1='命名函数_1';
                return this 
            }
            function fun2() {
                this.ccfun2='命名函数_2'    
            }
            let unnameFun1=function(){
                this.ccunnameFun1='匿名函数_return this 1'
                return this 
            }
            let unnameFun2=function(){
                this.ccunnameFun2='匿名函数_2 un return'    
            }
            
            let arrowFun1=()=>{
                this.ccarrow1 ='箭头函数_1';
                debugger
                return this     
            }
            let arrowFun2=function(){
                this.ccarrow2 ='箭头函数__2'
                
            }
            //测试命名函数
            console.log('----------return this;new----------')
            // 带this返回
            var fun1_new=new fun1();
            console.log(fun1_new.ccfun1)//命名函数_1  返回的this中绑定了指定变量
            console.log(window.ccfun1)//undefined  此变了未绑定在window上 说明函数创建的时候 this是函数内部的this,或者调用者非window
            console.log('----------return this;un new----------')
            var fun1_unnew=fun1();
            console.log(fun1_unnew===window) //true 此处证明 直接调用函数,不使用new创建,函数内部的this指向window
            console.log(window.ccfun1) //命名函数_1
            console.log('----------unreturn this;new----------')
            var fun2_new=new fun2();
            console.log(fun2_new.ccfun2)//命名函数_2  此处证明 return this不重要可以省略
            console.log(window.ccfun2)//undefined  
            var fun2_unnew=fun2();
            console.log(fun2_unnew===window) //此处证明 在不使用new 和return的情况 返回值既不是函数调用者也不是window
            console.log(fun2_unnew) //undefined 此处证明 直接调用函数,不适用new创建,函数内部的
            console.log(window.ccfun2) //命名函数_2
    
            /*  总结 命名函数
                1:new 一定会有返回 返回值是其调用者
                var fun1_new=new fun1() <==> var fun1_new=new fun1(this:fun1_new);
                2:直接调用函数,函数内部的this会指向window 此时return 决定是否有返回
                var fun1_new=fun1() <==> var fun1_new=fun1(this:window);
            */
    
            //测试匿名函数
            console.log('------匿名函数----return this;new----------')
            // 带this返回
            var unnameFun1_new=new unnameFun1();
            console.log(unnameFun1_new.ccunnameFun1)//匿名函数_return this 1  同上命名函数测试
            console.log(window.ccunnameFun1)//undefined  同上命名函数
            console.log('----------return this;un new----------')
            var unnameFun1_unnew=unnameFun1();
            console.log(unnameFun1_unnew===window) //true 此处证明 直接调用函数,不使用new创建,函数内部的this指向window
            console.log(unnameFun1_unnew.ccunnameFun1) //命名匿名函数_return this 1函数_1
            console.log('----------unreturn this;new----------')
            var unnameFun2_new=new unnameFun2();
            console.log(unnameFun2_new.ccunnameFun2)//命名函数_2  此处证明 return this不重要可以省略
            console.log(window.ccunnameFun2)//undefined  
            var unnameFun2_unnew=unnameFun2();
            console.log(unnameFun2_unnew===window) //此处证明 在不使用new 和return的情况 返回值既不是函数调用者也不是window
            console.log(unnameFun2_unnew) //undefined 此处证明 直接调用函数,不适用new创建,函数内部的
            console.log(window.ccunnameFun2) //命名函数_2
    
            /*  总结 匿名函数
                1:new 一定会有返回 返回值是其调用者
                var fun1_new=new fun1() <==> var fun1_new=new fun1(this:fun1_new);
                2:直接调用函数,函数内部的this会指向window 此时return 决定是否有返回
                var fun1_new=fun1() <==> var fun1_new=fun1(this:window);
            */
            console.log('------箭头函数----return this;new----------')
            //let arrowFun1_new = new arrowFun1();
            //console.log(arrowFun1_new.ccarrow1)//error 箭头函数不能new 使用
            let arrowFun1_unnew=arrowFun1();
            console.log(arrowFun1_unnew.ccarrow1)//error 箭头函数不能new 使用
            console.log(window==arrowFun1_unnew)//true  箭头函数内部使用this==window
            let arrowFun2_unnew=arrowFun2();
            console.log(window==arrowFun2_unnew)//false  箭头函数是否有返回值由return决定
    
                总结 一  命名函数 和 匿名函数 中的this
                    1 函数中的this由调用者决定 new创建的函数 函数的调用者是创建函数的变量,非new方法调用函数 函数的调用者将是window
                    2 new 和 return同时决定是否产生返回值,new决定由返回值的优先级高于return ,在不存在new的情况下 由return决定
                    3 如果想通过创建者调用函数内部参数及方法 应该在函数内部使用'this.xxx'进行绑定
    
                    二 箭头函数
                    1 箭头函数不能使用new 创建函数实例
                    2 箭头函数是否有返回值由return决定
                    3 箭头函数内的this指向window
                    三 call,apply,bind中的this             
                      这三个函数作用就是更改调用者中this的指向,很多教程介绍是传入对象调用调用者
    中函数,有点拗口和不好理解,这种说法把传入对象当成主体和执行者,有点类似于你请鲍鱼,你是原对象,
    请吃鲍鱼是执行方法,鲍鱼是方法中this绑定的喜欢的吃食物,现在通过call,apply,bind绑定对象,
    这个对象用同事表示,同事喜欢吃的是龙虾,绑定之后的结果就变成你请吃龙虾,同事喜欢吃的食物替换
    请吃方法中的this绑定的食物,这个过程顺序说法是你请吃的朋友喜欢的龙虾,逆序说法是朋友让你请
    吃的东西是朋友喜欢的龙虾。理解起来有点绕,而我个人理解的就是我请吃东西 ,具体
    是什么东西,由我调用的对象决定,类似于obj2.myFun.call(db,'江西','深圳')中,db是被
    调用的对象,db对象替换了调用方法中的this,如果偏要解释成db对象调用了调用者的方
    法,两个的效果是一样的,执行的方法是同一个,this都是传入对象,如果方法中this的
    属性在传入对象中不存在,则这个属性为undefind。
                        
                  1 传入对象替换执行方法中的this
                  2 方法中的this是替换,不是深度复制
                  3 在没有传入对象的时候 ,执行方法中的this指向window
                    
    
                    四 扩展 如果单纯想通过返回值调用调用原函数方法 可以通过原型绑定
                        function Person(first, last, eye) {
                            this.firstName = first;
                            this.lastName = last;
                            this.eyeColor = eye;
                        }
    
                        Person.prototype.age=function(age){
                            this._age=age;
                        };
                        var p1 = new Person("John", "Doe", "blue");
                            p1.age(20);
                        var p2 = new Person("li", "li", "black");
                            p2.age(15);
                        console.log(p1._age) //20
                        console.log(p2._age) //12   
    
                        age();方法内的this执行被创建的对象      
                
    

    相关文章

      网友评论

          本文标题:关于js 中的this

          本文链接:https://www.haomeiwen.com/subject/vmyqrctx.html