摘要:回調(diào)函數(shù)中調(diào)用在回調(diào)函數(shù)中一般有兩種情況回調(diào)函數(shù)為匿名函數(shù)時(shí),回調(diào)函數(shù)的會指向,需要對回調(diào)函數(shù)。回調(diào)函數(shù)為箭頭函數(shù)時(shí),回調(diào)函數(shù)的會指向他的直接上層。
淺談-this
this簡單而又神秘,使用場景多變而又復(fù)雜,這造就了它成為了初級javascript開發(fā)人員不愿接觸的東西,高級javascript都想探究的東西。文本亦是對this的致敬。
this是什么?
this是當(dāng)前執(zhí)行環(huán)境的上下文,通常由函數(shù)的調(diào)用方式?jīng)Q定其值。
this的原理
首先,從函數(shù)的調(diào)用開始
函數(shù)的調(diào)用一般有三種情況(ES5中)
1.foo(p1,p2);
2.obj.foo(p1,p2);
3.foo().call(context,p1,p2);//或者apply
通常情況下,大部分童鞋常用的都是前兩種方式,只有在不得不綁定context的情況下才會使用第三種。其中,第三種方式,才是函數(shù)調(diào)用的正確方式。
foo().call(context,p1,p2);
之所以,我們在使用前兩種方式也能正常的運(yùn)行,這其實(shí)就是一種語法糖而已,在js運(yùn)行機(jī)制中,會把前兩種調(diào)方式,當(dāng)做下面的方式進(jìn)行處理
foo(p1, p2) 等價(jià)于 foo.call(undefined, p1, p2) obj.foo(p1, p2) 等價(jià)于 obj.foo.call(obj, p1, p2)
因此,如果我們以后再調(diào)用函數(shù)時(shí),能準(zhǔn)確的找到context,就可以唯一的確認(rèn)this的值
this的使用場景
3.1 全局環(huán)境使用
無論是否在嚴(yán)格模式下,在全局執(zhí)行環(huán)境中(在任何函數(shù)體外部)this 都指向全局對象。
// 在瀏覽器中, window 對象同時(shí)也是全局對象:
console.log(this === window); // true
var a=1;
console.log(this.a) //1
console.log(window.a) //1
3.2 普通函數(shù)中調(diào)用
在非嚴(yán)格模式下,且this的值沒有被調(diào)用函數(shù)設(shè)置,this 的值默認(rèn)指向全局對象。
funnction func(){ console.log(this) } //瀏覽器環(huán)境中 func() // window //node環(huán)境中 func() // global
在嚴(yán)格模式下,this的值如果不設(shè)置,就是是undefined
funnction func(){ "use strict" console.log(this) } func() === undefined; // true
3.3 作為對象中的方法調(diào)用
var obj={
name:"我是對象obj", ofun:function(){ console.log(this.name) } } var name="我是全局name"; var func= obj.ofun; obj.ofun(); //我是對象obj func(); //我是全局name
這里有兩點(diǎn)需要注意:
1.函數(shù)作為對象的方法進(jìn)行調(diào)用時(shí),this指向當(dāng)前的對象。 2.對象中的函數(shù)方法名存儲的僅是一個(gè)函數(shù)的地址(地址中會有該函數(shù)的屬性:[[value]、[[writable]]、[[enumerable]]、[[congifable]]) 當(dāng)把一個(gè)對象的方法賦值給另一個(gè)變量(例如:func)時(shí),引擎會將函數(shù)多帶帶保存在內(nèi)存中,然后再將函數(shù)的地址賦值給foo屬性的value屬性。
3.4 構(gòu)造函數(shù)中使用
this在構(gòu)造函數(shù)中使用,值為實(shí)例化的對象
function Fun(name){ this.name=name; this.speak=function(){ console.log(this.name); } } var fun1=new Fun("jack"); fun1.speak(); var fun2=new Fun("rose"); fun2.speak();//rose
3.5 bind/call/apply
this再被bind/call/apply強(qiáng)制綁定上下文執(zhí)行環(huán)境時(shí),屬于硬綁定。
function foo(somerthing){ console.log(this.a); } var obj={ a:2 } var bar = function(){ foo.call(obj); }; bar(); //2 //硬綁定的bar不可能再修改它的this bar.call(window);//2 }
硬綁定的典型應(yīng)用場景就是創(chuàng)建一個(gè)包裹函數(shù),傳入所有的參數(shù)并返回接收到的所有值;
function foo(somerthing){ console.log(this.a,something); return this.a +something; } var obj={ a:2 } var bar = function(){ return foo.apply(obj,arguments); }; var b=bar(3);// 2 3 console.log(b);//5
由于硬綁定是一種非常常用的模式,所以在ES5中提供了內(nèi)置的方法Function.prototype.bind,它的用法如下;
function foo(somerthing){ console.log(this.a,something); return this.a +something; } var obj={ a:2 } var bar=foo.bind(obj); var b=bar(3);// 2 3 console.log(b);//5
call,apply,bind方法的區(qū)別:
a:第一個(gè)參數(shù)都是要綁定的上下文執(zhí)行環(huán)境,即this的值。
b:都可在函數(shù)調(diào)用時(shí)傳遞參數(shù)。call,bind方法需要直接傳入,而apply方法需要以數(shù)組的形式傳入。
c:call,apply方法是在調(diào)用之后立即執(zhí)行函數(shù),而bind方法沒有立即執(zhí)行,需要將函數(shù)再執(zhí)行一遍。有點(diǎn)閉包的味道。
d:改變this對象的指向問題不僅有call,apply,bind方法,也可以使用that/self等變量來固定this的指向。
3.6 回調(diào)函數(shù)中調(diào)用
在回調(diào)函數(shù)中一般有兩種情況: 1. 回調(diào)函數(shù)為匿名函數(shù)時(shí),回調(diào)函數(shù)的this會指向window,需要對回調(diào)函數(shù)bind(this)。 2. 回調(diào)函數(shù)為箭頭函數(shù)時(shí),回調(diào)函數(shù)的this會指向他的直接上層。
var obj = { name: "test for call-func", ofun: function(){ //undefined 丟失 setTimeout(function(){ console.log(this.name) }, 100); //work well 硬綁定 setTimeout(function(){ console.log(this.name) }.bind(this), 100);//test for call-func // arrow function test for call-func setTimeout( () => console.log(this.id), 100) } }; obj.ofun();
3.7 自執(zhí)行函數(shù)
自執(zhí)行或者立即執(zhí)行函數(shù)中的this指向Window
首先自執(zhí)行函數(shù)的幾種調(diào)用方式
//常見的有兩種: (function(){})() (function(){}())//w3c推薦方式 //只有表達(dá)式才能被執(zhí)行符號()執(zhí)行 +function test(){}();//+ - ! =等運(yùn)算符可以使前面的函數(shù)成為表達(dá)式,加上后面()可立即執(zhí)行。 //函數(shù)聲明無法立即執(zhí)行一個(gè)函數(shù),但是函數(shù)表達(dá)式可以 var a = function(){}();//這種是函數(shù)表達(dá)式,后面有()可以立即執(zhí)行。成為一個(gè)立即執(zhí)行函數(shù)。
var obj = { number: 3, xxx: (function () { console.log(this + "--")//立即執(zhí)行函數(shù)中的this指向window,因?yàn)榱⒓磮?zhí)行函數(shù)是window調(diào)用的 console.log(this.number + "~~~")//刪除上面一行,此處this.number返回undefined return function () { console.log(this.number + "】") this.number += 7; console.log(this + "+") } })() } obj.xxx() //相當(dāng)于obj.xxx.call(),所以此處的this指向obj console.log(obj.number) //10
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/102849.html
摘要:相信很多剛剛學(xué)習(xí)的新手都會有同感,當(dāng)看一段代碼時(shí),發(fā)現(xiàn)里面有很多,但是這些到底是指向哪里卻沒有那么清楚,為了搞清楚這些到底是什么情況,特地花點(diǎn)時(shí)間總結(jié)如下幾點(diǎn)最普遍的表示全局對象表示全局對象輸出為解析設(shè)置全局變量初始值為,當(dāng)調(diào)用函數(shù)之后改變 相信很多剛剛學(xué)習(xí)js的新手都會有同感,當(dāng)看一段js代碼時(shí),發(fā)現(xiàn)里面有很多this,但是這些this到底是指向哪里卻沒有那么清楚,為了搞清楚這些th...
摘要:將作用域賦值給變量這里的作用域是,而不是將作用域賦值給一個(gè)變量閉包返回瀏覽器中內(nèi)存泄漏問題大家都知道,閉包會使變量駐留在內(nèi)存中,這也就導(dǎo)致了內(nèi)存泄漏。 上一章我們講了匿名函數(shù)和閉包,這次我們來談?wù)勯]包中作用域this的問題。 大家都知道,this對象是在運(yùn)行時(shí)基于函數(shù)的執(zhí)行環(huán)境綁定的,如果this在全局就是[object window],如果在對象內(nèi)部就是指向這個(gè)對象,而閉包卻是在運(yùn)行...
摘要:工廠模式優(yōu)點(diǎn)集中實(shí)例化,可以傳參等缺點(diǎn)分不清屬于哪個(gè)對象我們先來談?wù)剝?yōu)點(diǎn),看例子集中實(shí)例化返回實(shí)例化對象返回返回不難看出,工廠模式比上面的例子減少了很多代碼。 ECMAscript開發(fā)的兩種模式:1.過程化 2.OOP(面向?qū)ο? 面向?qū)ο蟮恼Z言有一個(gè)標(biāo)志,那就是類的概念,而通過類可以創(chuàng)建任意多個(gè)具有相同屬性的方法的對象。但是ECMAscript中沒有類的概念! 又談作用域 首先...
摘要:想要解決這樣的問題的話,可以借助構(gòu)造函數(shù)也可以叫做偽造對象或經(jīng)典繼承。這種方式實(shí)現(xiàn)非常簡單,就是在子對象的構(gòu)造函數(shù)中調(diào)用父對象的構(gòu)造函數(shù)。 原型式繼承 原型式繼承,就是一定一個(gè)函數(shù),該函數(shù)中創(chuàng)建一個(gè)臨時(shí)性的構(gòu)造函數(shù),將作為參數(shù),傳入的對象作為這個(gè)構(gòu)造函數(shù)的原型,最后返回這個(gè)構(gòu)造函數(shù)的實(shí)例對象 /*定義函數(shù):用于實(shí)現(xiàn)對象之間的繼承 參數(shù): obj:表示繼承關(guān)系中的父級對象...
摘要:對其的解釋為概述監(jiān)視一個(gè)對象的某個(gè)屬性是否發(fā)生變化在該屬性變化時(shí)立即觸發(fā)指定的回調(diào)函數(shù)語法參數(shù)想要監(jiān)視值是否發(fā)生變化的指定對象的某個(gè)屬性的屬性名稱當(dāng)指定的屬性發(fā)生變化時(shí)執(zhí)行的回調(diào)函數(shù)在內(nèi)查看其聲明如下可以看到這兩個(gè)方法是只針對內(nèi)核的瀏覽器使 MDN 對其的解釋為: 概述: 監(jiān)視一個(gè)對象的某個(gè)屬性是否發(fā)生變化,在該屬性變化時(shí)立即觸發(fā)指定的回調(diào)函數(shù). 語法: object....
閱讀 2913·2021-10-14 09:42
閱讀 1262·2021-09-24 10:32
閱讀 2980·2021-09-23 11:21
閱讀 2859·2021-08-27 13:10
閱讀 3346·2019-08-29 18:41
閱讀 2208·2019-08-29 15:16
閱讀 1218·2019-08-29 13:17
閱讀 903·2019-08-29 11:22