电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

JavaScript 的 this 原理

瀏覽:88日期:2023-11-10 17:06:34
一、問題的由來

學懂 JavaScript 語言,一個標志就是理解下面兩種寫法,可能有不一樣的結果。

var obj = { foo: function () {}};var foo = obj.foo;// 寫法一obj.foo()// 寫法二foo()

上面代碼中,雖然obj.foo和foo指向同一個函數,但是執行結果可能不一樣。請看下面的例子。

var obj = { foo: function () { console.log(this.bar) }, bar: 1};var foo = obj.foo;var bar = 2;obj.foo() // 1foo() // 2

這種差異的原因,就在于函數體內部使用了this關鍵字。很多教科書會告訴你,this指的是函數運行時所在的環境。對于obj.foo()來說,foo運行在obj環境,所以this指向obj;對于foo()來說,foo運行在全局環境,所以this指向全局環境。所以,兩者的運行結果不一樣。

這種解釋沒錯,但是教科書往往不告訴你,為什么會這樣?也就是說,函數的運行環境到底是怎么決定的?舉例來說,為什么obj.foo()就是在obj環境執行,而一旦var foo = obj.foo,foo()就變成在全局環境執行?

本文就來解釋 JavaScript 這樣處理的原理。理解了這一點,你就會徹底理解this的作用。

二、內存的數據結構

JavaScript 語言之所以有this的設計,跟內存里面的數據結構有關系。

var obj = { foo: 5 };

上面的代碼將一個對象賦值給變量obj。JavaScript 引擎會先在內存里面,生成一個對象{ foo: 5 },然后把這個對象的內存地址賦值給變量obj。

JavaScript 的 this 原理

也就是說,變量obj是一個地址(reference)。后面如果要讀取obj.foo,引擎先從obj拿到內存地址,然后再從該地址讀出原始的對象,返回它的foo屬性。

原始的對象以字典結構保存,每一個屬性名都對應一個屬性描述對象。舉例來說,上面例子的foo屬性,實際上是以下面的形式保存的。

JavaScript 的 this 原理

{ foo: { [[value]]: 5 [[writable]]: true [[enumerable]]: true [[configurable]]: true }}

注意,foo屬性的值保存在屬性描述對象的value屬性里面。

三、函數

這樣的結構是很清晰的,問題在于屬性的值可能是一個函數。

var obj = { foo: function () {} };

這時,引擎會將函數單獨保存在內存中,然后再將函數的地址賦值給foo屬性的value屬性。

JavaScript 的 this 原理

{ foo: { [[value]]: 函數的地址 ... }}

由于函數是一個單獨的值,所以它可以在不同的環境(上下文)執行。

var f = function () {};var obj = { f: f };// 單獨執行f()// obj 環境執行obj.f()四、環境變量

JavaScript 允許在函數體內部,引用當前環境的其他變量。

var f = function () { console.log(x);};

上面代碼中,函數體里面使用了變量x。該變量由運行環境提供。

現在問題就來了,由于函數可以在不同的運行環境執行,所以需要有一種機制,能夠在函數體內部獲得當前的運行環境(context)。所以,this就出現了,它的設計目的就是在函數體內部,指代函數當前的運行環境。

var f = function () { console.log(this.x);}

上面代碼中,函數體里面的this.x就是指當前運行環境的x。

var f = function () { console.log(this.x);}var x = 1;var obj = { f: f, x: 2,};// 單獨執行f() // 1// obj 環境執行obj.f() // 2

上面代碼中,函數f在全局環境執行,this.x指向全局環境的x。

JavaScript 的 this 原理

在obj環境執行,this.x指向obj.x。

JavaScript 的 this 原理

回到本文開頭提出的問題,obj.foo()是通過obj找到foo,所以就是在obj環境執行。一旦var foo = obj.foo,變量foo就直接指向函數本身,所以foo()就變成在全局環境執行。

標簽: JavaScript
相關文章:
主站蜘蛛池模板: 河北凯普威医疗器材有限公司,高档轮椅系列,推车系列,座厕椅系列,协步椅系列,拐扙系列,卫浴系列 | 苏州西装定制-西服定制厂家-职业装定制厂家-尺品服饰西装定做公司 | 标准品网_标准品信息网_【中检计量】 | 粉末包装机-给袋式包装机-全自动包装机-颗粒-液体-食品-酱腌菜包装机生产线【润立机械】 | 河南橡胶接头厂家,河南波纹补偿器厂家,河南可曲挠橡胶软连接,河南套筒补偿器厂家-河南正大阀门 | 苏州教学设备-化工教学设备-环境工程教学模型|同科教仪 | SOUNDWELL 编码器|电位器|旋转编码器|可调电位器|编码开关厂家-广东升威电子制品有限公司 | Brotu | 关注AI,Web3.0,VR/AR,GPT,元宇宙区块链数字产业 | 量子管通环-自清洗过滤器-全自动反冲洗过滤器-北京罗伦过滤技术集团有限公司 | 雨水收集系统厂家-雨水收集利用-模块雨水收集池-徐州博智环保科技有限公司 | 【星耀裂变】_企微SCRM_任务宝_视频号分销裂变_企业微信裂变增长_私域流量_裂变营销 | 青岛代理记账_青岛李沧代理记账公司_青岛崂山代理记账一个月多少钱_青岛德辉财税事务所官网 | 盐城网络公司_盐城网站优化_盐城网站建设_盐城市启晨网络科技有限公司 | 橡胶弹簧|复合弹簧|橡胶球|振动筛配件-新乡市永鑫橡胶厂 | 定制液氮罐_小型气相液氮罐_自增压液氮罐_班德液氮罐厂家 | 电动葫芦|手拉葫芦|环链电动葫芦|微型电动葫芦-北京市凌鹰起重机械有限公司 | 高效节能电机_伺服主轴电机_铜转子电机_交流感应伺服电机_图片_型号_江苏智马科技有限公司 | 磁力抛光机_磁力研磨机_磁力去毛刺机-冠古设备厂家|维修|租赁【官网】 | 创富网-B2B网站|供求信息网|b2b平台|专业电子商务网站 | sfp光模块,高速万兆光模块工厂-性价比更高的光纤模块制造商-武汉恒泰通 | 不锈钢轴流风机,不锈钢电机-许昌光维防爆电机有限公司(原许昌光维特种电机技术有限公司) | SMC-SMC电磁阀-日本SMC气缸-SMC气动元件展示网 | 开云(中国)Kaiyun·官方网站-登录入口 | 广东机电安装工程_中央空调工程_东莞装饰装修-广东粤标建设有限公司 | 筛分机|振动筛分机|气流筛分机|筛分机厂家-新乡市大汉振动机械有限公司 | 河南橡胶接头厂家,河南波纹补偿器厂家,河南可曲挠橡胶软连接,河南套筒补偿器厂家-河南正大阀门 | 废水处理-废气处理-工业废水处理-工业废气处理工程-深圳丰绿环保废气处理公司 | 餐饮小吃技术培训-火锅串串香培训「何小胖培训」_成都点石成金[官网] | 芝麻黑-芝麻黑石材厂家-永峰石业 | 无锡网站建设_企业网站定制-网站制作公司-阿凡达网络 | 水压力传感器_数字压力传感器|佛山一众传感仪器有限公司|首页 | 水平垂直燃烧试验仪-灼热丝试验仪-漏电起痕试验仪-针焰试验仪-塑料材料燃烧检测设备-IP防水试验机 | ◆大型吹塑加工|吹塑加工|吹塑代加工|吹塑加工厂|吹塑设备|滚塑加工|滚塑代加工-莱力奇塑业有限公司 | 打包钢带,铁皮打包带,烤蓝打包带-高密市金和金属制品厂 | 压缩空气检测_气体_水质找上海京工-服务专业、价格合理 | 电动百叶窗,开窗器,电动遮阳百叶,电动开窗机生产厂家-徐州鑫友工控科技发展有限公司 | 液氨泵,液化气泵-淄博「亚泰」燃气设备制造有限公司 | 彭世修脚_修脚加盟_彭世修脚加盟_彭世足疗加盟_足疗加盟连锁_彭世修脚技术培训_彭世足疗 | 时代北利离心机,实验室离心机,医用离心机,低速离心机DT5-2,美国SKC采样泵-上海京工实业有限公司 工业电炉,台车式电炉_厂家-淄博申华工业电炉有限公司 | 天津热油泵_管道泵_天津高温热油泵-天津市金丰泰机械泵业有限公司【官方网站】 | 真石漆,山东真石漆,真石漆厂家,真石漆价格-山东新佳涂料有限公司 |