国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

node.js|vue.js|jquery|angularjs|React|json|js教程|

服務器之家 - 編程語言 - JavaScript - js教程 - JavaScript this關鍵字的深入詳解

JavaScript this關鍵字的深入詳解

2021-12-31 16:37JAVA_樸先生 js教程

這篇文章主要給大家介紹了關于JavaScript this關鍵字的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

一、前言

this關鍵字JavaScript中最復雜的機制之一。它是一個很特別的關鍵字,被自動定義在所有函數的作用域中。對于那些沒有投入時間學習this機制的JavaScript開發者來說,this的綁定一直是一件非常令人困惑的事。

JavaScript this關鍵字的深入詳解

二、了解this

學習this的第一步是明白this既不指向函數自身也不指向函數的詞法作用域,你也許被這樣的解釋誤導過,但其實它們都是錯誤的。隨著函數使用場合的不同,this的值會發生變化。但總有一條原則就是 JS中的this代表的是當前行為執行的主體 ,在JS中主要研究的都是函數中的this,但并不是說只有在函數里才有this, this實際上是在函數被調用時發生的綁定,它指向什么完全取決于函數在哪里被調用 。如何的區分this呢?

三、this到底是誰

這要分情況討論,常見有五種情況:

1、函數執行時首先看函數名前面是否有".",有的話,"."前面是誰,this就是誰;沒有的話this就是window

function fn(){
 console.log(this);
}
var obj={fn:fn};
fn();//this->window
obj.fn();//this->obj
function sum(){
 fn();//this->window
}
sum();
var oo={
 sum:function(){
 console.log(this);//this->oo
 fn();//this->window
 }
};
oo.sum();

2、自執行函數中的this永遠是window

(function(){ //this->window })();
 ~function(){ //this->window }();

3、給元素的某一個事件綁定方法,當事件觸發的時候,執行對應的方法,方法中的this是當前的元素,除了IE6~8下使用attachEvent(IE一個著名的bug)

DOM零級事件綁定

oDiv.onclick=function(){
 //this->oDiv
 };

DOM二級事件綁定

oDiv.addEventListener("click",function(){
 //this->oDiv
 },false);

在IE6~8下使用attachEvent,默認的this就是指的window對象

oDiv.attachEvent("click",function(){
 //this->window
 });

我們大多數時候,遇到事件綁定,如下面例子這種,對于IE6~8下使用attachEvent不必太較真

function fn(){
 console.log(this);
}
document.getElementById("div1").onclick=fn;//fn中的this就是#divl
document.getElementById("div1").onclick=function(){
console.log(this);//this->#div1
fn();//this->window
};

4、在構造函數模式中,類中(函數體中)出現的this.xxx=xxx中的this是當前類的一個實例

function CreateJsPerson(name,age){
//瀏覽器默認創建的對象就是我們的實例p1->this
this.name=name;//->p1.name=name
this.age=age;
this.writeJs=function(){
console.log("my name is"+this.name +",i can write Js");
 };
//瀏覽器再把創建的實例默認的進行返回
}
var p1=new CreateJsPerson("尹華芝",48);

必須要注意一點: 類中某一個屬性值(方法),方法中的this需要看方法執行的時候,前面是否有".",才能知道this是誰 。大家不妨看下接下來的這個例子,就可明白是啥意思。

function Fn(){
this.x=100;//this->f1
this.getX=function(){
console.log(this.x);//this->需要看getX執行的時候才知道
 }
}
var f1=new Fn;
f1.getX();//->方法中的this是f1,所以f1.x=100
var ss=f1.getX;
ss();//->方法中的this是window ->undefined

5.call、apply和bind

我們先來看一個問題,想在下面的例子中this綁定obj,怎么實現?

var obj={name:"浪里行舟"};
function fn(){
console.log(this);//this=>window
}
fn();
obj.fn();//->Uncaught TypeError:obj.fn is not a function

如果直接綁定obj.fn(),程序就會報錯。這里我們應該用fn.call(obj)就可以實現this綁定obj,接下來我們詳細介紹下call方法:

call方法的作用:

①首先我們讓原型上的call方法執行,在執行call方法的時候,我們讓fn方法中的this變為第一個參數值obj;然后再把fn這個函數執行。

②call還可以傳值,在嚴格模式下和非嚴格模式下,得到值不一樣。

//在非嚴格模式下
var obj={name:"浪里行舟 "};
function fn(num1,num2){
console.log(num1+num2);
console.log(this);
}
fn.call(100,200);//this->100 num1=200 num2=undefined
fn.call(obj,100,200);//this->obj num1=100 num2=200
fn.call();//this->window
fn.call(null);//this->window
fn.call(undefined);//this->window
//嚴格模式下 
fn.call();//在嚴格模式下this->undefined
fn.call(null);// 在嚴格模式 下this->null
fn.call(undefined);//在嚴格模式下this->undefined

**apply和call方法的作用是一模一樣的,都是用來改變方法的this關鍵字并且把方法

執行,而且在嚴格模式下和非嚴格模式下對于第一個參數是null/undefined這種情況的規

律也是一樣的。**

兩者唯一的區別:call在給fn傳遞參數的時候,是一個個的傳遞值的,而apply不是一個個傳,而是把要給fn傳遞的參數值統一的放在一個數組中進行操作。但是也相當子一個個的給fn的形參賦值。 總結一句話:call第二個參數開始接受一個參數列表,apply第二個參數開始接受一個參數數組

fn.call(obj,100,200);
fn.apply(obj,[100,200]);

bind:這個方法在IE6~8下不兼容,和call/apply類似都是用來改變this關鍵字的 ,但是和這兩者有明顯區別:
fn.call(obj,1,2);//->改變this和執行fn函數是一起都完成了

fn.bind(obj,1,2);//->只是改變了fn中的this為obj,并且給fn傳遞了兩個參數值1、2,
 但是此時并沒有把fn這個函數執行
var tempFn=fn.bind(obj,1,2);
tempFn(); //這樣才把fn這個函數執行

bind體現了預處理思想:事先把fn的this改變為我們想要的結果,并且把對應的參數值也準備好,以后要用到了,直接的執行即可。

call和apply直接執行函數,而bind需要再一次調用。

var a ={
 name : "Cherry",
 fn : function (a,b) {
 console.log( a + b)
 }
 }
 var b = a.fn;
 b.bind(a,1,2)

JavaScript this關鍵字的深入詳解

上述代碼沒有執行,bind返回改變了上下文的一個函數,我們必須要手動去調用:

b.bind(a,1,2)() //3

必須要聲明一點:遇到第五種情況(call apply和bind),前面四種全部讓步。

四、箭頭函數this指向

箭頭函數正如名稱所示那樣使用一個“箭頭”(=>)來定義函數的新語法,但它優于傳統的函數,主要體現兩點: 更簡短的函數并且不綁定this 。

var obj = {
 birth: 1990,
 getAge: function () {
 var b = this.birth; // 1990
 var fn = function () {
 return new Date().getFullYear() - this.birth; // this指向window或undefined
 };
 return fn();
 }
};

現在,箭頭函數完全修復了this的指向, 箭頭函數沒有自己的this,箭頭函數的this不是調用的時候決定的,而是在定義的時候處在的對象就是它的this 。

換句話說, 箭頭函數的this看外層的是否有函數,如果有,外層函數的this就是內部箭頭函數的this,如果沒有,則this是window 。

<button id="btn1">測試箭頭函數this_1</button>
 <button id="btn2">測試箭頭函數this_2</button>
 <script type="text/javascript"> 
 let btn1 = document.getElementById('btn1');
 let obj = {
 name: 'kobe',
 age: 39,
 getName: function () {
 btn1.onclick = () => {
 console.log(this);//obj
 };
 }
 };
 obj.getName();
 </script>

JavaScript this關鍵字的深入詳解

上例中,由于箭頭函數不會創建自己的this,它只會從自己的作用域鏈的上一層繼承this。其實可以簡化為如下代碼:

let btn1 = document.getElementById('btn1');
 let obj = {
 name: 'kobe',
 age: 39,
 getName: function () {
 console.log(this)
 }
 };
 obj.getName();

那假如上一層并不存在函數,this指向又是誰?

<button id="btn1">測試箭頭函數this_1</button>
 <button id="btn2">測試箭頭函數this_2</button>
 <script type="text/javascript"> 
 let btn2 = document.getElementById('btn2');
 let obj = {
 name: 'kobe',
 age: 39,
 getName: () => {
 btn2.onclick = () => {
 console.log(this);//window
 };
 }
 };
 obj.getName();
 </script>

JavaScript this關鍵字的深入詳解

上例中,雖然存在兩個箭頭函數,其實this取決于最外層的箭頭函數,由于obj是個對象而非函數,所以this指向為Window對象

由于this在箭頭函數中已經按照詞法作用域綁定了,所以, 用call()或者apply()調用箭頭函數時,無法對this進行綁定,即傳入的第一個參數被忽略 :

var obj = {
 birth: 1990,
 getAge: function (year) {
 var b = this.birth; // 1990
 var fn = (y) => y - this.birth; // this.birth仍是1990
 return fn.call({birth:2000}, year);
 }
};
obj.getAge(2018); // 28

擴展閱讀

箭頭函數-廖雪峰

JS中的箭頭函數與this

this、apply、call、bind

總結

到此這篇關于JavaScript this關鍵字深入詳解的文章就介紹到這了,更多相關JavaScript this關鍵字內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://segmentfault.com/a/1190000038976928

延伸 · 閱讀

精彩推薦
  • js教程基于 Next.js 的 SSR/SSG 方案了解一下?

    基于 Next.js 的 SSR/SSG 方案了解一下?

    服務端渲染(SSR,Server Side Render)與客戶端渲染(CSR,Client Side Render)的核心區分點簡單來說就是完整的 HTML 文檔在服務端還是瀏覽器里組裝完成。...

    DYBOY4472021-12-27
  • js教程使用 JavaScript 進行數據分組最優雅的方式

    使用 JavaScript 進行數據分組最優雅的方式

    對數據進行分組,是我們在開發中經常會遇到的需求,使用 JavaScript 進行數據分組的方式也有很多種,但是由于沒有原生方法的支持,我們自己實現的數據...

    code秘密花園4352021-12-27
  • js教程JS實現頁面側邊欄效果探究

    JS實現頁面側邊欄效果探究

    這篇文章主要介紹了JS實現頁面側邊欄效果探究,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以...

    行舟客4752021-12-29
  • js教程詳解JavaScript中分解數字的三種方法

    詳解JavaScript中分解數字的三種方法

    這篇文章主要介紹了在JavaScript中分解數字的三種方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下...

    Hunter網絡安全6072021-12-27
  • js教程mapboxgl實現帶箭頭軌跡線的代碼

    mapboxgl實現帶箭頭軌跡線的代碼

    這篇文章主要介紹了mapboxgl實現帶箭頭軌跡線的代碼,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下...

    GIS兵器庫9142021-12-27
  • js教程JavaScript canvas實現文字時鐘

    JavaScript canvas實現文字時鐘

    這篇文章主要為大家詳細介紹了JavaScript canvas實現文字時鐘,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    _Adoph6092021-12-29
  • js教程js定時器出現第一次延遲的原因及解決方法

    js定時器出現第一次延遲的原因及解決方法

    在本篇文章里小編給大家整理的是一篇關于js定時器出現第一次延遲的原因及解決方法,對此有需要的朋友們可以學習下。...

    宋宋大人4932021-12-24
  • js教程前端經常會用到的JavaScript方法封裝

    前端經常會用到的JavaScript方法封裝

    前端經常會用到的JavaScript方法封裝都有哪些呢?我們一起來看一下吧!...

    Find一只程序猿11312021-12-30
主站蜘蛛池模板: 亚洲人成网站在e线播放 | 亚洲一区二区免费看 | 国产免费视频在线 | 国产极品探花 | 我不卡一区 | 成人免费网站 | 欧美成人综合 | 人人叉人人 | 久草电影网 | 亚洲免费一区二区 | 久久久久高清 | 日韩欧美自拍 | 91国在线产 | 黄色一级片免费 | av在线一区二区三区 | 午夜爱爱毛片xxxx视频免费看 | 日韩国产一区二区三区 | 日韩视频在线一区二区 | 国产亚洲精品美女久久久久久久久久 | 久久国产精品偷 | a视频在线| 亚洲 中文 欧美 日韩 在线观看 | 久久99精品国产麻豆婷婷洗澡 | 日本一区二区在线视频 | 亚洲视频www | 高清在线一区二区 | 欧美一区二区三区在线视频 | 国产成人精品久久二区二区 | 欧美日韩电影 | 精品二区 | 在线视频自拍 | 99亚洲精品 | 欧美日韩电影一区二区 | 欧美精品一区二区三区四区五区 | 久久精品香蕉 | 国产欧美日韩一级大片 | 国产欧美日韩在线 | 最新黄网 | 日韩欧美视频免费 | 免费国产一区二区 | 国产在线精品一区 |