摘要:構(gòu)造函數(shù)例子例子中,因?yàn)闃?gòu)造函數(shù)的指向構(gòu)造出來的實(shí)例,所以是用構(gòu)造出來的對象,那么就是指向。構(gòu)造函數(shù)中要注意的一點(diǎn)是默認(rèn)情況下,構(gòu)造函數(shù)是沒有,但是非要加一個(gè)的話。
this
this對于初學(xué) JS 的新人來說,是一道坎,看到this就暈頭暈?zāi)X,腦容量一下不夠用了。
先來說下判斷this結(jié)論
this是函數(shù)調(diào)用時(shí)call的第一個(gè)參數(shù)
this只有在函數(shù)執(zhí)行的時(shí)候才能被確定,實(shí)際指向調(diào)用它那個(gè)對象(上一級(jí))
先來看下函數(shù)常用的幾種調(diào)用方式
fn(a,b) fn.name(a,b) var f = fn.name; f(a,b) fn.call(undefined,a,b) fn.apply(undefined,[a,b])
上面三種調(diào)用方法對于新人很熟悉,而對后面兩種方法比較陌生,自然也就弄不明白this含義了。
改寫下函數(shù)的調(diào)用方式就會(huì)發(fā)現(xiàn)這兩種是等價(jià)的,回到上面說的結(jié)論,call的第一個(gè)參數(shù)是this,a、b才是傳進(jìn)去的參數(shù)。
fn(a,b) === fn.call(undefined,a,b) === window.fn.apply(window,[a,b])
明白了這點(diǎn),大部分的this就不難判斷了,新人在判斷this時(shí)只需改寫函數(shù)調(diào)用方式就能知道this指向了。
this例子下面方法中暫且不討論嚴(yán)格模式,this的指向
例子1:
var user = "window" function fn(){ var user = "object"; console.log(this.user); //windwow } fn(); //改寫 window.fn.call(window)
fn是全局對象window的方法
例子2:
var user = "window" var obj = { user:"object", fn:function(){ console.log(this.user); //object } } obj.fn(); //改寫 obj.fn.call(obj)
這里的fn是被obj調(diào)用的,所以fn內(nèi)部的this指向obj內(nèi)部的user。
你可能會(huì)有疑惑了,這里是不是可以改寫成window.obj.fn.call(window),往下看
例子3:
var user = "window" var obj = { user:"object", fn:function(){ console.log(this.user); //object } } window.obj.fn(); //改寫 window.obj.fn.call(window.obj)
先看下面例子
例子4:
var user = "window" var obj = { user:"object", fn1:{ user:"function", fn2:function(){ console.log(this.user) //function } } } obj.fn1.fn2(); //改寫 obj.fn1.call(obj.fn1)
例子3中正常情況下都是把window給省略的,這里寫出來是為了和例子4做對比。
假設(shè)例子4中obj對象是不是window下的方法,而是和window平級(jí)(實(shí)際不存在這種假設(shè),容易理解)。
這里是鏈?zhǔn)秸{(diào)用,this的最終指向是調(diào)用它的上一層對象fn1,但是不能改寫成obj.fn1.call(fn1),只有window可以省略。
例子5:
var user = "window" var obj = { user:"object", fn1:{ user:"function", fn2:function(){ console.log(this.user) //window } } } var a = obj.fn1.fn2; a() //改寫 window.a.call(window)
先看下面例子
例子6:
var a = {user:"window"} var obj = { user:"object", fn1:{ user:"function", fn2:function(){ console.log(this.user) //window } } } obj.fn1.fn2.call(a);
看到例子5和例子6是不是已經(jīng)暈了。
例子5中,var a = obj.fn1.fn2只是賦值,并沒用執(zhí)行,而真正執(zhí)行的時(shí)候,a是window下的方法,所以fn2內(nèi)部的this指向window下的user。
例子6中,call的第一個(gè)參數(shù)是a,那this肯定指向a的user,因?yàn)轱@示綁定優(yōu)先級(jí)高于隱示綁定。
那你可能要問什么是顯示綁定,什么是隱示綁定呢?
obj.fn() //隱示綁定 obj.fn.call(obj) //顯示綁定
也就是說你改寫后的調(diào)用就是顯示綁定。
new構(gòu)造函數(shù)例子7:
function Fn(){ this.user = "object"; } var a = new Fn(); console.log(a.user); //object
例子7中,因?yàn)闃?gòu)造函數(shù)的this指向構(gòu)造出來的實(shí)例,所以a是用new構(gòu)造出來的對象,那么this就是指向a。
構(gòu)造函數(shù)中要注意的一點(diǎn)是:默認(rèn)情況下,構(gòu)造函數(shù)是沒有return,但是非要加一個(gè)return的話。
如果return的是引用類型值,那么構(gòu)造函數(shù)的this就指向return的對象
如果return的是基本類型值,那么構(gòu)造函數(shù)的this就指向構(gòu)造出來的實(shí)例化函數(shù)
this基本應(yīng)用就是這些,做一些實(shí)操練習(xí)鞏固一下
this實(shí)操實(shí)操1:
function X(){ return object = { name:"object", f1(x){ x.f2() //② 改寫 options.f2.call(options) }, f2(){ console.log(this) } } } var options = { name:"options", f1(){}, f2(){ console.log(this) //③ 運(yùn)行這個(gè)this,打印 options 函數(shù) } } var x = X(); x.f1(options); //① 改寫 object.f1.call(object,options)
看到this就馬上改寫,不改寫就做,肯定錯(cuò)。
分析
首先把x.f1(options)改寫object.f1.call(object,options)
x.f1(options)調(diào)用object對象內(nèi)部f1方法,把options函數(shù)作為參數(shù)傳入,所以 object內(nèi)部f1(x)中的x是options函數(shù)
f2內(nèi)部的this指向options
實(shí)操2:
function X(){ return object = { name:"object", f1(x){ x.f2.call(this) //② 這里是顯示綁定,改寫 options.f2.call(object) }, f2(){ console.log(this) } } } var options = { name:"options", f1(){}, f2(){ console.log(this) //③ 運(yùn)行這個(gè) this 打印 object } } var x = X() x.f1(options) //① 改寫 object.f1.call(object,options)
分析
首先把x.f1(options)改寫object.f1.call(object,options)
f1內(nèi)部的this指向object
把x.f2.call(this)改寫options.f2.call(object),這里的.call(this)是顯示指定
f2內(nèi)部的this就是object
實(shí)操3:
function X(){ return object = { name:"object", options:null, //③ options = options f1(x){ this.options = x //② 改寫 object.options = options this.f2() //③ 改寫 object.f2.call(object) }, f2(){ this.options.f2.call(this) //④ 顯示綁定,改寫 object.options.f2.call(object) } } } var options = { name:"options", f1(){}, f2(){ console.log(this) //⑤運(yùn)行這個(gè) this,打印 object } } var x = X() x.f1(options) //① 改寫 object.f1.call(object,options)
分析
首先把x.f1(options) 改寫object.f1.call(object,options)
f1內(nèi)的this指向object,options作為參數(shù)傳進(jìn)來
把this.options = x改寫object.options = options,同時(shí)也把this.f2()改寫稱object.f2()
把this.options.f2.call(this) 改寫object.options.f2.call(object),.call(this)是顯示綁定
f2內(nèi)部的this就是object
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/107912.html
摘要:大名鼎鼎的閉包面試必問。閉包的作用是什么。看到閉包在哪了嗎閉包到底是什么五年前,我也被這個(gè)問題困擾,于是去搜了并總結(jié)下來。關(guān)于閉包的謠言閉包會(huì)造成內(nèi)存泄露錯(cuò)。閉包里面的變量明明就是我們需要的變量,憑什么說是內(nèi)存泄露這個(gè)謠言是如何來的因?yàn)椤? 本文為饑人谷講師方方原創(chuàng)文章,首發(fā)于 前端學(xué)習(xí)指南。 大名鼎鼎的閉包!面試必問。請用自己的話簡述 什么是「閉包」。 「閉包」的作用是什么。 首先...
摘要:說明最近看到這樣一段代碼問三行的輸出分別是什么覺得有點(diǎn)意思,和大家一起來聊聊。說到這里,這道題基本上可以解決了,希望大家能聽明白我上面說的話,下面的就簡單了。 說明 最近看到這樣一段代碼 function fun(n,o){ console.log(o); return { fun:function(m){ return fun...
摘要:說明最近看到這樣一段代碼問三行的輸出分別是什么覺得有點(diǎn)意思,和大家一起來聊聊。說到這里,這道題基本上可以解決了,希望大家能聽明白我上面說的話,下面的就簡單了。 說明 最近看到這樣一段代碼 function fun(n,o){ console.log(o); return { fun:function(m){ return fun...
摘要:說明最近看到這樣一段代碼問三行的輸出分別是什么覺得有點(diǎn)意思,和大家一起來聊聊。說到這里,這道題基本上可以解決了,希望大家能聽明白我上面說的話,下面的就簡單了。 說明 最近看到這樣一段代碼 function fun(n,o){ console.log(o); return { fun:function(m){ return fun...
閱讀 1181·2021-09-22 15:24
閱讀 2285·2019-08-30 15:44
閱讀 2615·2019-08-30 10:55
閱讀 3355·2019-08-29 13:25
閱讀 1639·2019-08-29 13:09
閱讀 1391·2019-08-26 14:05
閱讀 1379·2019-08-26 13:58
閱讀 1985·2019-08-26 11:57