1. 程式人生 > >js閉包中this的指向問題及三種解決方法

js閉包中this的指向問題及三種解決方法

下面是一個問題,物件方法中定義的子函式,子函式執行時this指向哪裡?
三個問題:
    (1)以下程式碼中列印的this是個什麼物件?
    (2)這段程式碼能否實現使myNumber.value加1的功能?
    (3)在不放棄helper函式的前提下,有哪些修改方法可以實現正確的功能?

var myNumber = {
  value: 1,
  add: function(i){
    var helper = function(i){
        console.log(this);
          this.value += i;
    }
    helper(i);
  }
}
myNumber.add(1
);

1.this指向window物件(因為匿名函式的執行具有全域性性,所以其this物件指向window);2.不能實現value加1(每個函式在被呼叫時都會自動取得兩個特殊變數,this和arguments,內部函式在搜尋這兩個物件時,只會搜尋到其活動物件為止,所以不能實現訪問外部函式的this物件);
3.修改程式碼實現正確功能
第一種方法:

var myNumber={
    value:1,
    add:function(i){
        var that=this;//定義變數that用於儲存上層函式的this物件
        var helper=function
(i){
console.log(that); that.value+=i; } helper(i); } } myNumber.add(1);

第二種方法:

var myNumber={
    value:1,
    add:function(i){
        var helper=function(i){
            this.value+=i;
        }
        helper.apply(this,[i]);//使用apply改變helper的this物件指向,使其指向myNumber物件
} } myNumber.add(1);

第三種方法

var myNumber={
    value:1,
    add:function(i){
        var helper=function(i){
            this.value+=i;
        }.bind(this,i);//使用bind繫結,和apply相似,只是它返回的是對函式的引用,不會立即執行
        helper(i);
    }
}
myNumber.add(1);

相關推薦

jsthis指向問題解決方法

下面是一個問題,物件方法中定義的子函式,子函式執行時this指向哪裡? 三個問題:     (1)以下程式碼中列印的this是個什麼物件?     (2)這段程式碼能否實現使myNumber.value加1的功能?     (3)在不放棄helper函式

jsthis指向情況

js中this指向的幾種情況 一、全域性作用域或者普通函式自執行中this指向全域性物件window //全域性作用域 console.log(this);//Window //普通函式 function fn(){ console.log(this); //Wi

改變this指向常用方法

JavaScript中this的是一個值得深入的話題,下面總結了改變this指向的3種常用方法。首先弄清楚函式這個概念:函式本身就是一種特殊型別,要時刻明白一點,函式也可以認為是一種變數。 1.通過物

OLE:物件的類沒有在註冊資料庫註冊 問題的解決方法

我在網上下載了破解版的SAS9.3,用了一段時間之後,今天開啟就填出一個提示框: OLE:物件的類沒有在註冊資料庫中註冊  啟用該物件所需的應用程式不可用。是否用“轉換……”將其轉換為或啟用為另一型別

前端知識小節--js改變this指向方式

在寫程式碼完成專案的過程中我們經常會遇到需要改變this指向來實現功能的時候,以下三種方式是常用的改變this指向的方法: 1.call call中的引數有多個,如: aa.call(obj,num1,num2); obj是函式執行的作用域,num1,num2是要給函式傳的

js改變this指向個常用方法bind,call和apply

一.bind:說起bind,很多人都會想起jquery中的bind繫結方法,給元素繫結事件,今天所講的bind則是js的原生方法---可改變this的指向,下面我們來看演示:var name = 'sally'; function sayName(){ return

js的理解以及this的理解

閉包其實很好理解,但是由於經常把this和閉包綁在一起,從而加大了理解的難度,如果將他們分開考慮,那就清晰多了。 閉包 閉包並不是js首創,在許多語言中都支援閉包,如schemer、ruby等。如果沒有閉包,像js這樣的支援高階函式特性的語言將是一個噩夢。 靜態作用域 動態作用域 var nam

js的沙箱模式

<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <

this的指代,以及四函式呼叫this的指代

    Q:// (1)這裡this指代什麼?function a(){    // (2)這裡this指代什麼?    var c = 2;    function b(){        // (3)這裡呢?this又指代什麼?        return c;    }    return b;}a()

Electron與jQuery$符號沖突的解決方法

jquer obj define export tro conf jquery blog ack   在Electron工程中引用jQuery時,經常會出現以下錯誤: Uncaught ReferenceError: $ is not defined   解決的具體方

c++ STLsort函式的使用方法

複習一下~ STL,C++中的標準模板庫, 使用起來方便並且效率較高; sort函式有三種用法: 一:對基本型別陣列從小到大排序 sort( 陣列名+n1,陣列名+n2); 將陣列中下標從n1到n2的元素進行從小到大排序,不包括n2,通過n1,n2 可以對整

js $ is not function 的解決方法

將格式改成如下形式: 一 、 jQuery(document).ready(function(){ jQuery(function () { //code }); 二、 jQuery(document).ready(function($){ $(

PHP no input file specified 解決方法

重新 cgi put 主機 tro robot 解析 進行 例如 一.IIS Noinput file specified (IIS上報的錯誤) 方法一:改PHP.ini中的doc_root行,打開ini文件註釋掉此行,然後重啟IIS 方法二: 請

selenium報錯Element is not clickable at point解決方法

使用Selenium時,觸發點選事件,經常報如下異常: Element is not clickable at point   1、未載入 沒加載出來就等待元素加載出來,再往下執行。 可以使用python庫time 不過最好還是使用selenium自帶WebDriver

LCA 解決方法講解 (附加例題)

  LCA(Least Common Ancestors) 即最近公共祖先,是指這樣一個問題:在有根樹中,找出某兩個結點u和v最近的公共祖先(另一種說法,離樹根最遠的公共祖先)。 一、線上演算法ST演算法     所謂線上即輸入一個詢問,要立即返回答案,才可進行下一次詢問。

eclipsealt+/失效的幾解決方法

1、次方法用於沒有一點提示的情況:依次開啟eclipse上面的windows ——preferences ——java ——editor —— content assist ,在右上方有一行“select the proposal kinds contained in t

執行緒間操作無效: 從不是建立控制元件的執行緒訪問它的解決方法

今天遇到這個問題,百度了下,把解決的方法總結出來。 我們在ui執行緒建立的子執行緒操作ui控制元件時,系統提示錯誤詳細資訊為: 執行緒間操作無效: 從不是建立控制元件“XXX”的執行緒訪問它。 就我知道的有三種方法,先看一下msdn的介紹: 訪問 Windows 窗

mybatis返回map型別資料空值欄位不顯示(解決方法)

一、查詢sql新增每個欄位的判斷空 IFNULL(rate,'') as rate11 二、ResultType利用實體返回,不用map 三、springMVC+mybatis查詢資料,返回resultType=”map”時,如果資料為空的欄位,則該欄位省略不顯示,可以

小程式請求豆瓣API報403的解決方法

微信小程式使用wx.request API請求豆瓣公開api的時候,會報一個403(Forbidden)的錯誤。 這是為什麼呢?是由於來自小程式的呼叫過多,豆瓣來自於小程式的呼叫被禁止。這裡收集以下三種方法解決此問題(設定代理):     1、使用 https://d

PHP刪除HTMl標籤的解決方法

直接取出想要取出的標記 複製程式碼程式碼如下: <?php     //取出br標記     function strip($str) { $str=str_replace("<br>","",$str); //$str=htmlspecialchars($str); return