不安分的this

来源:http://www.cnblogs.com/hewasdrunk/archive/2017/08/17/7381609.html
-Advertisement-
Play Games

不安分的this 前言:關於javascript中的this,上網一搜一大片的文章。驚! 而我個人認為要想分清this,就有必要先搞清楚“對象”。 目錄: 一.函數對象的認識 二.this 一.函數對象的認識 post出概念: 每逢過節,親戚朋友都會問,小羅你的對象呢? 這裡所指的對象:是指小羅我感 ...


不安分的this

 

 前言:關於javascript中的this,上網一搜一大片的文章。驚!

 

而我個人認為要想分清this,就有必要先搞清楚“對象”。

 

 

目錄:

一.函數對象的認識

二.this 

 

 

 

一.函數對象的認識

post出概念:

每逢過節,親戚朋友都會問,小羅你的對象呢?

這裡所指的對象:是指小羅我感覺合適的某個異性。是指實體:實例。

1:小羅感覺合適(對應電腦語言就是:方法)對人友善

2:異性(屬性)女人

那麼回答親戚就說:黃某某

我想表達的是,對象是指某一類人,當使用的時候是明確的某個人。

函數

插入內容,如下引用:

 

函數對象與其他用戶所定義的對象有著本質的區別,這一類對象被稱之為內部對象

例如日期對象(Date)、數組對象(Array)、字元串對象 (String)都屬於內部對象。

這些內置對象的構造器是由JavaScript本身所定義的:通過執行new Array()這樣的語句返回一個對象,JavaScript內部有一套機制來初始化返回的對象,而不是由用戶來指定對象的構造方式。

在JavaScript中,函數對象對應的類型是Function,正如數組對象對應的類型是Array,日期對象對應的類型是Date一樣,可以通過 new Function()來創建一個函數對象,也可以通過function關鍵字來創建一個對象。

下麵兩行代碼都是創建一個數組對象myArray:
var myArray=[];
//等價於
var myArray=new Array();
同樣,下麵的兩段代碼也都是創建一個函數myFunction:
function myFunction(a,b){
return a+b;
}
//等價於
var myFunction=new Function("a","b","return a+b"); 

 

出自:雨中無傘V-藍色“認識js中的function和this

 

 就是說:

 看到用function關鍵字創建的,和用new Function()創建的內容稱為函數對象(function)

 而this就是指向函數對象。

 

二.this

判斷this所指的具體對象方法:

step1:找到函數真正被調用執行的位置(運行時的位置)

step2:查看有沒有閉包或者直接調用再或者call與apply

step3: this: 當前方法屬於誰,this就是誰!

 

 

關鍵字詞:this關鍵字總是返回某個具體對象。再說的詳細一些,就是屬性或方法“當前”所在的某個對象。(重點一

 

(1)身處全局變數中

案例:

var name="全局";
function getName(){
    var name="局部";
    return this.name;
};
alert(getName());//全局

step1:找到函數真正被調用執行的位置(運行時的位置)

既是:

alert(getName());

step2:查看有沒有閉包或者直接調用再或者call與apply

沒有這些內容,不會跳了出來。

step3: this: 當前方法屬於誰,this就是誰!

這裡只是聲明瞭那一類,而沒有指出是哪一個人。那麼就會預設指向window

則getName返回的this.name其實是window.name,因此alert出來的是“全局”!

 

(2)身處局部變數中

在解說之前,要插入一些內容

構造函數:

var obj = new Object();

 

如上,稱new 調用的函數為構造函數,構造函數和普通函數區別僅僅在於是否使用了new來調用,它們的返回值也會不同

所謂“構造函數”,就是專門用來生成“對象”的函數。

特點:1可以生成多個對象

2可以通過.來為對象添加屬性和方法

obj.name = 'Byron';
obj.printName = function(){
    console.log(obj.name);
};

 

可以等價於

var obj = {
    name: 'Byron',
    printNmae: function(){
        console.log(obj.name);
    }
}

 

自動化就要使用函數嵌套了

function createObj(name, age){
  var obj = {
    name: name,
    age: age,
    printName: function(){
            console.log(this.name);
        }
  };
  return obj;
}

var obj3 = createObj('Byron', 30);
obj3.printName();

 

but:構造出來的對象類型都是Object,沒有識別度

可以改造為

function Person(nick, age){
    this.nick = nick;
    this.age = age;
    this.sayName = function(){
            console.log(this.nick);
    }
}
var p1 = new Person();

 

參考文章:謙行的“JavaScript面向對象

 

 

有瞭如上的基礎,就可以看下方的例子了。

案例:

var name="全局";
var twobin={
    name:"局部",
    getName:function(){
        return this.name;
    }
};
alert(twobin.getName());

step1:找到函數真正被調用執行的位置(運行時的位置)

既是:

alert(twobin.getName());

step2:查看有沒有閉包或者直接調用再或者call與apply

沒有這些內容,不會跳了出來。

step3: this: 當前方法屬於誰,this就是誰!

這裡指出是哪一個人twobin。那麼就會預設指向window

則getName返回的this.name其實是twobin.name,因此alert出來的是“局部”!

 

 

(3)身處閉包中

var name="全局";
var twobin={
    name:"局部",
    getName:function(){
        return function(){
            return this.name;
        };
    }
};
alert(twobin.getName()());

step1:找到函數真正被調用執行的位置(運行時的位置)

既是:

alert(twobin.getName()());

step2:查看有沒有閉包或者直接調用再或者call與apply

有,所以不能根據第一步,而是

匿名函數的運行時位置來判斷。

function (){

    return this.name;

};來確認位置

step3: this: 當前方法屬於誰,this就是誰!

匿名函數所在的對象是window

匿名函數返回的this.name其實是window.name,因此alert出來的就是“全局”!

 

那麼,如何在閉包中使得this身處在twobin中呢?

var name="全局";
var twobin={
    name:"局部",
    getName:function(){
        var that=this;
        return function(){
            return that.name;
        };
    }
};
alert(twobin.getName()());

step1:找到函數真正被調用執行的位置(運行時的位置)

既是:

alert(twobin.getName());

step2:查看有沒有閉包或者直接調用再或者call與apply

有,但是this不再匿名函數中

step3: this: 當前方法屬於誰,this就是誰!

這裡指出是哪一個人twobin。那麼就會預設指向window

則getName返回的this.name其實是twobin.name,因此alert出來的是“局部”!

 

(4)call與apply中的this

在JavaScript中能管的住this的估計也就非call與apply莫屬了。

call與apply就像this的父母一般,讓this住哪它就得住哪,不得不聽話!

var name="全局";
var twobin={
    name:"局部",
};
function getName(){
    alert(this.name);
}
getName(twobin);
getName.call(twobin);

step1:找到函數真正被調用執行的位置(運行時的位置)

既是:

getName(twobin);

step2:查看有沒有閉包或者直接調用再或者call與apply

沒有這些內容,不會跳了出來。

step3: this: 當前方法屬於誰,this就是誰!

這裡只是聲明瞭那一類,而沒有指出是哪一個人。那麼就會預設指向window

則getName返回的this.name其實是window.name,因此alert出來的是“全局”!

getName.call(twobin);

其中,call指定this的安身之處就是在twobin對象,因為this被迫只能在twobin那安家,則此時this指向twobin對象, this.name其實是twobin.name,因此alert出來的是“局部”!

 

這些是我本人話了一個下午的時間總結出來的,應該有些不足。我相信在日後的工作上會慢慢的提煉出更為準確的知識。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • [1]引入 [2]過渡組件 [3]過渡類名 [4]transition [5]animation [6]自定義類名 [7]過渡時間 ...
  • 在html5之前,瀏覽器要實現數據的存儲,一般都是用cookie,但是cookie有功能變數名稱和大小限定. html5流行之後,可以通過localStorage和sessionStorage實現瀏覽器端的數據存儲,這兩者有什麼特點呢? sessionStorage sessionStorage屬於臨時會話 ...
  • 反柯里化 相反,反柯里化的作用在與擴大函數的適用性,使本來作為特定對象所擁有的功能的函數可以被任意對象所用.即把如下給定的函數簽名, 轉化成一個函數形式,簽名如下: 這就是 反柯里化的形式化描述。 例如,下麵的一個簡單實現: 解釋: uncurrying是定義在Function的prototype上 ...
  • 持續集成(Continuous Integration)是一種軟體開發實踐,即團隊開發成員經常集成它們的工作,通過每個成員每天至少集成一次,也就意味著每天可能會發生多次集成。每次集成都通過自動化的構建(包括編譯,發佈,自動化測試)來驗證,從而儘早地發現集成錯誤,減少一些反覆的工作等等,使團隊更加有效 ...
  • 1 超時調用setTimeout() 顧名思義,超時調用的意思就是在一段實際之後調用(在執行代碼之前要等待多少毫秒) setTimeout()他可以接收兩個參數: 1 要執行的代碼或函數 2 毫秒(在執行代碼之前要等待多少毫秒) clearTimeout() clearTimeout,表示清除定時器 ...
  • 在上面的源碼中,用到了隨機數運算,取隨機數的實現可以達成非常多的隨機特效: 取隨機數有以下幾種方法: ...
  • 概述 續接上文的密碼校驗要求: ![xuqiu.jpg][1] 這個需求有兩個難點,一,是如何使用正則匹配所有半形英文標點符號,二,是如何驗證密碼段中在要求的四種(大寫字母,小寫字母,數字,標點符號)類型中至少存在三種。 第一個難點:如何使用正則匹配所有半形英文標點符號在上文中已經得以解決,所以在這 ...
  • relative:是相對於自己來定位的,例如:#demo{position:relative;top:-50px;},這時#demo會在相對於它原來的位置上移50px。如果它之前的元素也為relative並有偏移,則兩個偏移不想加,relative只在它原本所在位置上進行偏移。relative 不脫 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...