摘要:關(guān)于的全面解析下頁面鏈接的調(diào)用位置調(diào)用位置就是函數(shù)在代碼中被調(diào)用的位置而不是聲明的位置,尋找調(diào)用位置就是尋找函數(shù)被調(diào)用的位置,最重要的是分析調(diào)用棧就是為了到達當(dāng)前執(zhí)行位置所調(diào)用的所有函數(shù)。因此,調(diào)用函數(shù)時被綁定到這個對象上,所以和是一樣的。
關(guān)于this的全面解析(下)頁面鏈接
this的調(diào)用位置調(diào)用位置就是函數(shù)在代碼中被調(diào)用的位置(而不是聲明的位置),尋找調(diào)用位置就是尋找“函數(shù)被調(diào)用的位置”,最重要的是分析調(diào)用棧(就是為了到達當(dāng)前執(zhí)行位置所調(diào)用的所有函數(shù))。
function baz() { //當(dāng)前調(diào)用棧是baz //當(dāng)前調(diào)用位置是全局位置 console.log("baz"); bar(); //<--bar的調(diào)用位置 } function bar() { //當(dāng)前的調(diào)用棧是baz->bar //因此當(dāng)前的調(diào)用位置在baz中 console.log("bar"); foo(); //<--foo的調(diào)用位置 } function foo() { //當(dāng)前的調(diào)用棧是baz->bar->foo //因此當(dāng)前的調(diào)用位置在bar中 console.log("foo"); } baz(); //<-baz的調(diào)用位置
把調(diào)用棧想象成一個函數(shù)調(diào)用鏈,如上圖代碼中的樣式,但是這種方法非常麻煩并且容易出錯。另一個查看調(diào)用棧的方法是使用瀏覽器的調(diào)試工具。
綁定規(guī)則首先需要找到調(diào)用位置,然后判斷尋求下列四條規(guī)則中的哪一條。
1 默認(rèn)綁定
首先介紹最常用的函數(shù)調(diào)用類型:獨立函數(shù)調(diào)用。可以把這條規(guī)則看作是無法應(yīng)用其他規(guī)則時的默認(rèn)規(guī)則。
function foo() { console.log(this.a); //<-this指向全局作用域 } var a = 2; foo(); //<-foo調(diào)用位置
在代碼中,foo()是直接使用不帶任何修飾的函數(shù)引用進行調(diào)用的,因此只能使用默認(rèn)綁定,無法應(yīng)用其他規(guī)則。
function foz() { "use strict"; console.log(this.a); //<--嚴(yán)格模式下不能將全局對象用于綁定 } foz(); //TypeError
2 隱藏綁定
另一條需要考慮的規(guī)則是調(diào)用位置是否有上下文對象,或者說是否被某個對象擁有或者包含,這種說法有時候會有誤導(dǎo)。
function foa() { console.log(this.a); } var foaObj = { a: "Hello", foa: foa //<--foa函數(shù)調(diào)用位置 } foaObj.foa();
foa函數(shù)在嚴(yán)格意義上來說不屬于foaObj對象。然而,調(diào)用位置會使用foaObj上下文來引用函數(shù),因此可以判斷為函數(shù)調(diào)用時,foaObj對象包含并引用它。
當(dāng)函數(shù)引用有上下文對象時,隱式綁定規(guī)則會把函數(shù)調(diào)用中的this綁定到這個上下文對象。因此,調(diào)用foa函數(shù)時this被綁定到foaObj這個對象上,所以this.a 和 foaObj.a 是一樣的。
然而,有一個常見的this綁定問題就是被隱式綁定的函數(shù)會丟失綁定對象,也就是說它會應(yīng)用默認(rèn)綁定,從而把this綁定到全局對象或undefined上。
function fob() { console.log(this.a); } var fobObj = { a: "Hello", fob: fob } var focObj = fobObj.fob; var a = 1; //a是全局對象的屬性 focObj();
focObj引用實際上是fob函數(shù),所以this綁定的是全局對象中的a。
3 顯式綁定
就像我們剛才看到的那樣,在分析隱式綁定時,我們必須在一個對象內(nèi)部包含一個指向函數(shù)的屬性,并通過這個屬性間接引用函數(shù),從而把this間接綁定到這個對象上。
JavaScript提供的絕大多數(shù)函數(shù)以及你自己創(chuàng)建的所有函數(shù)都可以使用call(…) 和 apply (…) 方法。
這兩個方法的第一參數(shù)是一個對象,是給this準(zhǔn)備的,接著在調(diào)用函數(shù)時將其綁定到this。因為你可以直接指定this的綁定對象,因此我們稱之為顯式綁定。
function fod() { console.log(this.a); } var fodObj = { a: 2 } fod.call(fodObj); //2
通過fod.call(…)方法,可以強制把this綁定到fodObj這個對象上。
然而,顯示綁定仍然無法解決之前提出的丟失綁定問題。
但是顯示綁定的一個變種可以解決這個問題。
function foh() { console.log(this.a); } var fohObj = { a: 2 } var baa = function() { foh.call(fohObj); } baa(); //2 setTimeout(baa, 100); //2 baa.call(window); //2
我們創(chuàng)建了一個baa函數(shù),并在它的內(nèi)部手動調(diào)用了foh.call(fohObj),因此強制把foh的this綁定到了fohObj上。無論之后如何調(diào)用函數(shù)baa,它總會手動在fohObj上調(diào)用foh。這種綁定是一種顯示的強制綁定,因此我們稱之為硬綁定。
硬綁定的典型應(yīng)用場景就是創(chuàng)建一個包裹函數(shù),負責(zé)接收參數(shù)并返回值。
function foi(something) { console.log(this.a, something); return this.a + something; } var foiObj = { a: 2 } var bae = function() { return foi.apply(foiObj, arguments); } var b = bae(3); console.log(b);
另一種使用方法是創(chuàng)建一個可以重復(fù)使用的輔助函數(shù)。
function fol(something) { console.log(this.a, something); return this.a + something; } function bind(fn, obj) { return function() { return fn.apply(obj, arguments); } } var folObj = { a: 3 } var bac = bind(fol, folObj); var c = bac(4); console.log(c);
4 new綁定
使用new來調(diào)用函數(shù),或者說發(fā)生構(gòu)造函數(shù)調(diào)用時,會自動執(zhí)行下面的操作。
1) 創(chuàng)建(或者說構(gòu)造)一個全新的對象。
2) 這個新對象會被執(zhí)行Prototype連接。
3) 這個新對象會綁定到函數(shù)調(diào)用的this。
4) 如果函數(shù)沒有返回其他對象,那么new表達式中的函數(shù)調(diào)用會自動返回這個新對象。
function abc(a) { this.a = a; } var x = new abc(10); console.log(x.a);
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/79663.html
摘要:關(guān)于的全棉解析上的文章地址判斷函數(shù)是否在中調(diào)用綁定如果是的話綁定的是新創(chuàng)建的對象。顯而易見,這種方式可能會導(dǎo)致許多難以分析和追蹤的。默認(rèn)在嚴(yán)格模式下綁定到,否則綁定到全局對象。 關(guān)于this的全棉解析(上)的文章地址 判斷this 函數(shù)是否在new中調(diào)用(new綁定)?如果是的話this綁定的是新創(chuàng)建的對象。 bar = new foo() 函數(shù)是否通過call、apply(顯式綁定...
摘要:調(diào)用棧就是為了到達當(dāng)前執(zhí)行位置所調(diào)用的所有函數(shù)。由于無法控制回調(diào)函數(shù)的執(zhí)行方式,因此就沒有辦法控制調(diào)用位置得到期望的綁定,下一節(jié)我們會介紹如何通過固定來修復(fù)這個問題。 在《你不知道的this》中我們排除了對于this的錯誤理解,并且明白了每個函數(shù)的this是在調(diào)用時綁定的,完全取決于函數(shù)的調(diào)用位置。在本節(jié)中我們主要介紹一下幾個主要內(nèi)容: 什么是調(diào)用位置 綁定規(guī)則 this詞法 調(diào)用...
摘要:在傳統(tǒng)的面向類的語言中,構(gòu)造函數(shù)是類中的一些特殊方法,使用初始化類是會調(diào)用類中的構(gòu)造函數(shù)。 在上一節(jié)中我們詳細介紹了this的兩種綁定方式,默認(rèn)綁定和隱式綁定,在這一節(jié)我們繼續(xù)介紹this的另外兩種綁定方式顯示綁定和new綁定。那么,我們要解決的問題當(dāng)然就是上一節(jié)中我們提到的:this丟失! 顯式綁定 在隱式綁定中,我們必須在一個對象的內(nèi)部包含一個指向函數(shù)的屬性,并通過這個屬性間接引用...
摘要:所以也就是說在沒有的基礎(chǔ)上,執(zhí)行代碼會在串池中創(chuàng)建一個,也會在堆內(nèi)存中再出來一個。不可變性的優(yōu)點安全性字符串不可變安全性的考慮處于兩個方面,數(shù)據(jù)安全和線程安全。 摘要: String基本特性,String源碼,為什么String不可變? 前言 基于字符串String在java中的地位,關(guān)于String的常識性知識就不多做介紹了,我們先來看一段代碼 public class Test {...
摘要:本文就來剖析下什么是是什么在創(chuàng)建代幣一篇,我們講到過代幣,和一樣,同樣是一個代幣標(biāo)準(zhǔn),官方簡要解釋是,簡寫為,多翻譯為非同質(zhì)代幣。返回合約代幣符號,盡管是可選,但強烈建議實現(xiàn),即便是返回空字符串。 本文首發(fā)于深入淺出區(qū)塊鏈社區(qū)原文鏈接:剖析非同質(zhì)化代幣ERC721-全面解析ERC721標(biāo)準(zhǔn)原文已更新,請讀者前往原文閱讀 什么是ERC-721?現(xiàn)在我們看到的各種加密貓貓狗狗都是基于ERC...
閱讀 3093·2021-11-22 09:34
閱讀 593·2021-11-22 09:34
閱讀 2437·2021-10-08 10:18
閱讀 3372·2021-09-22 15:57
閱讀 2585·2021-09-22 15:25
閱讀 2398·2019-08-30 15:54
閱讀 2093·2019-08-30 15:44
閱讀 1799·2019-08-29 11:18