分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 前端开发

JS 中的 this 总结

发布时间:2023-09-06 02:15责任编辑:赖小花关键词:暂无标签

JavaScript 中的 this:
this指向是在运行函数时确定的,而不是定义函数时候确定的
匿名函数的执行环境具有全局性,因此其this 对象通常指向window(在通过call()或apply()改变函数执行环境的情况下,this 就会指向其他对象)

全局上下文:无论是否在严格模式下,在全局执行上下文中(在任何函数体外)this都指代全局对象

    如:
        1、console.log(this === window); // true
        2、var girl={name:"amy",testThis:this}; console.log(girl.testThis); // window
          (可理解为:var girl=new Object(); girl.name="amy"; girl.testThis=this;(指向window)


函数上下文:在函数内部,this的取值取决于函数被调用的方式

    1、简单调用:
    function f1(){
      return this;
    }
    f1() === window; //在浏览器中,全局对象是window
    非严格模式下,且this的值不是由该调用设置时(具体说就是不由该调用通过 call、apply、bind 这些方法来设置),this的值默认指向全局对象 严格模式下,this将保持它进入执行上下文时的值 所以默认为undefined
    
    2、如果要想把 this 的值从一个上下文传到另一个,就要用 call 或者apply 方法
    
    3、bind方法:
    ECMAScript 5 引入了 Function.prototype.bind。调用f.bind(someObject)会创建一个与f具有相同函数体和作用域的函数,但是在这个新函数中,this将永久地被绑定到了bind的第一个参数,无论这个函数是如何被调用的
    
    4、箭头函数:this与封闭词法上下文的this保持一致(即this被设置为它创建时的上下文)。如果将this的值传给call、bind、apply,它将被忽略,不过仍然可以为为调用添加参数,不过第一个参数应设置为null
    
    5、作为对象的方法:当作为对象的方法被调用时,它们的this是调用该函数的对象,并且此时this的绑定只受最靠近的成员引用的影响
    
    6、原型链中的this:this指向的是调用该方法的对象,就像该方法在对象上一样

    7、getter(与setter)中的this:用作getter(或setter)的函数会把this绑定到获取(或设置)属性的对象上

    8、作为构造函数:this被绑定到正在构造的新对象(虽然构造器返回的默认值是this所指的那个对象,但它仍可以手动返回其他的对象)
    
    9、作为一个DOM事件处理函数:this指向触发事件的元素
    
    10、作为一个内联事件处理函数:this指向监听器所在的DOM元素
        如:
            1、<button onclick="alert(this.tagName.toLowerCase());"> Show this </button> this指向button(注意只有外层代码中的this是这样设置的)
            
            2、<button onclick="alert((function(){return this})());">  Show inner this </button> 这种情况下,没有设置内部函数的this,相当于函数简单调用的情况,所以它指向global/window对象

部分代码示例:

 ?1 <!DOCTYPE html> ?2 <html lang="en"> ?3 <head> ?4 ????<meta charset="UTF-8"> ?5 ????<title>This</title> ?6 </head> ?7 <body> ?8 ??9 <script> 10 ????//全局上下文:无论是否在严格模式下,在全局执行上下文中(在任何函数体外)this都指代全局对象 ?11 ????var girl={ 12 ????????name:"amy", 13 ????????testThis:this 14 ????}; 15 ????/* 16 ????????可理解为: 17 ????????var girl=new Ojbect(); 18 ????????girl.name="amy"; 19 ????????girl.testThis=this; 20 ????*/ 21 ????console.log(girl.testThis);//window 22 </script> 23 ?24 <script> 25 ????console.log("JS 是基于词法作用域的语言,函数在定义它的作用域中执行,而不是在调用它的作用域中执行"); 26 ????console.log("类的方法默认是不会绑定 this 的,作为对象的方法:当作为对象的方法被调用时,它们的this是调用该函数的对象,并且this的绑定只受最靠近的成员引用的影响"); 27 ????console.log("-----------About Amy --------------"); 28 ????var Amy={ 29 ????????????name:"Amy", 30 ????????????sex:"girl", 31 ????????????amyOutter:function(){ 32 ????????????????console.log("amyOutter:",this); 33 ????????????????return function(){ 34 ????????????????????console.log("amyAnonymous:",this); 35 ????????????????}; 36 ????????????} 37 ????????}; 38 ????console.log("----Amy.func amyOutter -----"); 39 ????var amy_anony=Amy.amyOutter(); 40 ????//输出: amyOutter: {name: "Amy", sex: "girl", amyOutter: ƒ} 41 ????// 解析:作为对象的方法调用 42 ?43 ????console.log("----Amy.func amyOutter quote-----"); 44 ????var quote=Amy.amyOutter;//获取Amy.amyOutter函数的引用 45 ????quote(); 46 ????//输出:amyOutter: Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …} 47 ????// 解析:这里相当于简单调用 48 ?????49 ????console.log("----Amy.func amyAnonymous-----"); 50 ????amy_anony(); 51 ????//输出: amyAnonymous: Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …} 52 ????// 解析:直接调用返回的匿名函数 53 ?54 ????amy_anony.call(Amy); 55 ????//输出: amyAnonymous: {name: "Amy", sex: "girl", amyOutter: ƒ} 56 ????// 解析:Amy用call调用返回的匿名函数 57 ?????58 </script> 59 ?60 <script> 61 ????console.log("-----------About Mike -----------"); 62 ????var Mike={ 63 ????????name:"Mike", 64 ????????sex:"boy", 65 ????????mikeOutter:function(){ 66 ????????????console.log("mikeOutter:",this); 67 ????????????(function(){ 68 ????????????????console.log("mikeAnonymous:",this); 69 ????????????})(); 70 ????????} 71 ????}; 72 ?73 ????console.log("----Mike.func mikeOutter---"); 74 ????Mike.mikeOutter(); 75 ????//输出: mikeOutter: {name: "Mike", sex: "boy", mikeOutter: ƒ} 76 ????// 解析:作为对象的方法调用 ??77 ????//输出: mikeAnonymous: Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …} 78 ????// 输出:window 解析:匿名函数被调用 79 ?80 ????console.log("----Mike.func mikeOutter quote-----"); 81 ????var quote=Mike.mikeOutter;//获取Mike.mikeOutter函数的引用 82 ????quote(); 83 ????//输出:mikeOutter: Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …} 84 ????// 解析:这里相当于简单调用 85 ????//输出: mikeAnonymous: Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …} 86 ????// 解析:匿名函数被调用 87 ?88 ????console.log("---Mike func call---"); 89 ????Mike.mikeOutter.call(Amy); 90 ????//输出: mikeOutter: {name: "Amy", sex: "girl", amyOutter: ƒ} 91 ????// 解析:Amy 用call调用返回的匿名函数 ?92 ????//输出:mikeAnonymous: Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …} 93 ????// 解析:匿名函数被调用 94 ?95 </script> 96 ?97 <script> 98 ????console.log("-----------About Guang -----------"); 99 ????var Guang={100 ????????name:"Guang",101 ????????sex:"boy",102 ????????GuangOutterOne:function(){103 ????????????console.log("GuangOutterOne:",this);104 ????????????var that=this;105 ????????????// 正确 that 中保留了对 this 的引用106 ????????????this.GuangOutterTwo(function(){107 ????????????????that.GuangOutterThree(); ???????????????108 ????????????});109 ????????????110 ????????????// 正确 匿名函数直接绑定 this111 ????????????// this.GuangOutterTwo(function(){112 ????????????// ????this.GuangOutterThree(); ???????????????113 ????????????// }.bind(this));114 115 ????????????// 出错 匿名函数作参数 this 为 window ,window 无 GuangOutterThree 方法116 ????????????// this.GuangOutterTwo(function(){117 ????????????// ????this.GuangOutterThree(); ???????????????118 ????????????// });119 ????????},120 ????????GuangOutterTwo:function(cb){121 ????????????console.log("GuangOutterTwo:",this);122 ????????????cb();123 ????????},124 ????????GuangOutterThree:function(){125 ????????????console.log("GuangOutterThree:",this);126 ????????}127 ????};128 129 ????console.log("----Guang.func GuangOutterOne---");130 ????Guang.GuangOutterOne();131 ????//输出:GuangOutterOne: {name: "Guang", sex: "boy", GuangOutterOne: ƒ, GuangOutterTwo: ƒ, GuangOutterThree: ƒ} 132 ????//解析:作为对象的方法调用 ?133 134 ????//输出: GuangOutterTwo: {name: "Guang", sex: "boy", GuangOutterOne: ƒ, GuangOutterTwo: ƒ, GuangOutterThree: ƒ}135 ????//解析: GuangOutterOne 中的 this 指向 Guang 调用 Guang 中的 GuangOutterTwo 方法136 137 ????//输出: GuangOutterThree: {name: "Guang", sex: "boy", GuangOutterOne: ƒ, GuangOutterTwo: ƒ, GuangOutterThree: ƒ}138 ????//解析: that 保留对 this 的引用 调用 Guang 中的 GuangOutterTwo 方法139 ???140 141 </script>142 143 <script>144 ????console.log("JS 是基于词法作用域的语言,函数在定义它的作用域中执行,而不是在调用它的作用域中执行");145 ????console.log("箭头函数:this与封闭词法上下文的this保持一致(即this 被设置为他被创建时的上下文)");146 ????var foo=(()=>this);147 ????/*148 ????????可以把箭头函数看成是149 ????????var foo=function(){150 ????????????//other code151 ????????????return this;152 ????????????//此处this所在的函数被创建时是在全局环境中 因为 this被设置为他被创建时的上下文 所以 this就被设置为window153 ????????};154 ????*/155 ????// 由下可见 无论如何,foo 中的 this 都被设置为他被创建时的上下文(在上面的例子中,就是全局对象)156 ????// 注意:对于箭头函数 如果将this传递给call、bind、或者apply,它将被忽略 不过你仍然可以为调用添加参数,不过第一个参数(thisArg)应该设置为null157 ????var obj = {foo: foo};158 ????console.log("直接调用:",foo()===window,", call调用:",obj.foo() === window,", apply调用:",foo.call(obj) === window,", bind绑定:",foo.bind(obj)() === window); // true true true true159 ????160 ???//这同样适用于在其他函数内创建的箭头函数:这些箭头函数的this被设置为封闭的词法上下文的161 ????console.log("-----------About John ------------------");162 ????var John={163 ????????name:"John",164 ????????johnOutter:function(){165 ????????????//console.log("johnOutter",this);//johnOutter中的this具体情况可参考上面的Amy和Mike实例166 ????????????var x=(()=>this);167 ????????????//此处this所在的函数被创建时是在johnOutter中 ?因为 this被设置为他被创建时的上下文 所以 this就被设置为 johnOutter 函数中的this168 ????????????return x;169 ????????}170 ????}171 172 ????var fn=John.johnOutter();//获取返回的函数 若去掉johnOutter中console.log语句的注释 输出:John 解析:解析:作为对象的方法调用 173 ????console.log("John.johnOutter():",fn());174 ????//输出:John.johnOutter(): Object { name: "John", johnOutter: johnOutter() }175 ????//解析:此时johnOutter函数由John调用 所以johnOutter函数中的this为John,而箭头函数的this被设置为johnOutter的this176 177 ????var quote=John.johnOutter;//获取John.johnOutter函数的引用178 ????console.log("quote:",quote()());179 ????//输出:window 180 ????//解析:此时quote获取johnOutter的引用,quote()相当于简单调用,所以johnOutter函数中的this为window,而箭头函数的this被设置为johnOutter的this181 ????182 ????/**183 ?????* 对于箭头函数:184 ?????* 1、确定箭头函数是在哪个执行环境中被创建的185 ?????* 2、根据执行环境确定this被设置为哪个执行环境186 ?????* 3、最后对函数的调用参考对象中的方法调用即可187 ?????* 总结可以简单理解为:188 ?????* 箭头函数的this在全局执行上下文创建时 它的this就是全局上下文中的this 189 ?????* 箭头函数的this在全局执行上下文创建时 它的this就是全局上下文中的this 190 ?????*/191 192 </script>193 194 </body>195 </html>

JS 中的 this 总结

原文地址:https://www.cnblogs.com/go4it/p/9678121.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved