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