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