關於 JS this

来源:https://www.cnblogs.com/gaobw/archive/2019/11/06/11807098.html
-Advertisement-
Play Games

關於 JS this "1. this 與 普通函數" "2. this 與 bind、call、apply" "3. this 與 箭頭函數" "4. this 與 return" + "4.1 返回 引用對象" + "4.2 返回 function對象" + "4.3 返回 數字,值對象" + ...


關於 JS this

1. this 與 普通函數

普通函數 this 永遠指向它的調用對象

var obj = {
    a:10,
    b:{
        a:20,
        fn:function(){
            console.log(this.a);
        }
    }
}
obj.b.fn(); //=> 20

對象 b 調用 fn 函數 this.a 為 20。

var obj2 = {
    a:10,
    b:{
        fn:function(){
            console.log(this.a);
        }
    }
}
obj2.b.fn(); //=> undefined

對象 b 中無 a 欄位, this.a 為 undefined。

var obj3 = {
    a:10,
    b:{
        a:20,
        fn:function(){
            console.log(this);
            console.log(this.a);
        }
    }
}
var j = obj3.b.fn;
j(); //=> window, undefined

這裡直接獲取里fn對象,沒有通過對象去調用。非嚴格模式下,this 預設指向全局對象window。

var obj4 = {
    a:10,
    b:{
        a:20,
        fn:function(){
            "use strict";
            console.log(this);
            console.log(this.a);
        }
    }
}
var g = obj4.b.fn;
g(); //=> undefined, TypeError: Cannot read property 'a' of undefined

而嚴格模式下, this 為 undefined。

2. this 與 bind、call、apply

function.bind(thisArg[, arg1[, arg2[, ...]]]) 最簡單的用法是創建一個函數,不論怎麼調用,這個函數都有同樣的 this 值。
function.call(thisArg, arg1, arg2, ...)、function.apply(thisArg, [argsArray]) call、apply 的作用類似都是為調用函數指定this。

function fn() {
    return this.user;
}

console.log(fn.call({ user: "li" })); //=> li

console.log(fn.apply({ user: "wang" })); //=> wang

var bfn = fn.bind({ user: "gao" });
console.log(bfn()); //=> gao


console.log(bfn.call({ user: "liu" })); //=> gao

console.log(bfn.apply({ user: "liu" })); //=> gao

console.log(bfn.bind({ user: "liu" })()); //=> gao

var obj = { user: 'zhang', f: fn, g: bfn };
console.log(obj.f(), obj.g()); //=>  zhang, gao

對 bind 產生的函數使用,再使用 call、apply、bind, 指向的 this 仍然是初次bind的值。

function list() {
    return Array.prototype.slice.call(arguments);
}
console.log(list(1, 2, 3)); //=> [1, 2, 3]

function list2(){
    if(arguments){
        arguments.__proto__.slice = Array.prototype.slice;
        return arguments.slice();
    }
}
console.log(list2(4, 5, 6)); //=> [4, 5, 6]

var leading37List = list.bind(null, 37);
console.log(leading37List()); //=> [37]
console.log(leading37List(1, 2, 3)); //=> [37, 1, 2, 3]

在函數代碼中,特殊對象 arguments 無需明確指出參數名,就能訪問它們。arguments 自帶 length 屬性, Array.prototype.slice.call(arguments) 可以理解成 arguments.slice()

3. this 與 箭頭函數

由於箭頭函數不綁定this,它會捕獲其所在(即定義的位置)上下文的this值, 作為自己的this值。

var obj = {
    a: 10,
    b: function () {
        console.log(this.a, this)
    },
    c: () => console.log(this.a, this),
}
obj.b(); //=> 10, Object{...}
obj.c(); //=> undefined, window{...} 

obj.c.apply({ a: 'apply' }); //=> undefined, window{...} 
obj.c.call({ a: 'call' }); //=> undefined, window{...} 
obj.c.bind({ a: 'bind' })(); //=> undefined, window{...} 

call() 、 apply() 、 bind() 方法對於箭頭函數來說只是傳入參數,對它的 this 毫無影響。

function fn() {
    this.a = 20;
    this.b = () => console.log(this.a, this);
}
console.log((new fn()).b()) //=> 20, fn {a: 20, b: ƒ}

箭頭函數不會創建自己的this,它只會從自己的作用域鏈的上一層繼承this。

var lam = (...r) => { 
    console.log(r); 
}
lam(1,2,3); //=> Array : [1, 2, 3]

箭頭函數沒有arguments,取而代之用rest參數…解決。

var B = ()=>{
  value:1;
}
var b = new B(); //=> TypeError: B is not a constructor

箭頭函數作為匿名函數,沒有構造函數,不能使用new。

4. this 與 return

如果返回值是 引用類型 對象,那麼this指向的就是那個返回的對象;
如果返回值是 非引用類型 對象那麼this還是指向函數的實例。

4.1 返回引用對象

function fn()  
{  
    this.user = '123';  
    return {};  
}
var a = new fn;  
console.log(a.user); //=> undefined

4.2 返回function對象

function fn()  
{  
    this.user = '123';  
    return function(){};
}
var a = new fn;  
console.log(a.user); //=> undefined

4.3 返回數字,值對象

function fn()  
{  
    this.user = '123';  
    return 123;
}
var a = new fn;  
console.log(a.user); //=> 123

4.4 返回undefined

function fn()  
{  
    this.user = '123';  
    return undefined;
}
var a = new fn;  
console.log(a.user); //=> 123

4.5 返回null

function fn()  
{  
    this.user = '123';  
    return null;
}
var a = new fn;  
console.log(a.user); //=> 123

返回目錄


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

-Advertisement-
Play Games
更多相關文章
  • 版權聲明:本文為xing_star原創文章,轉載請註明出處! 本文同步自http://javaexception.com/archives/225 最近線上報錯,有個用戶連續crash了10次左右,查看了下堆棧信息,發現是提示com.android.camera.action.CROP這個Inten ...
  • 版權聲明:本文為xing_star原創文章,轉載請註明出處! 本文同步自http://javaexception.com/archives/224 禁用EditText 這個其實很簡單,最簡單的一種方式,代碼如下 那麼還有其他的方式麽,我想應該是有的,以下的幾個api我並沒有做驗證 參考資料: ht ...
  • 在一個Vue的PC項目中,要求給錯誤圖片不要讓它顯示醜陋的圖片,就要給圖片寫一個失敗後的預設圖片, 在這裡寫了兩種方法, 第一種方法,也就是百度到的最多的代碼,就是給一張圖片一個預設值。 第二種問題,如果頁面中有很多地方都存在這個東西,那麼在不同的頁面中寫很對是很麻煩的。 就使用到了VUe的指令。 ...
  • 初級菜鳥的作品,各位大佬見笑了 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> ...
  • 這是一個悲傷的故事。某日清晨,距離版本轉測還剩一天,切圖仔的我正按照計劃有條不紊的畫頁面。當我點擊一個下拉彈框組件中分頁組件頁數過多而出現的向後 5 頁省略號時,悲劇開始了,彈框被收回了。情景再現 問題 問題的表象很簡單,使用的是組件庫的下拉彈窗組件,在組件中使用到了分頁組件,當點擊分頁組件的向後 ...
  • ## 因為初級的內容較多,所以選了一些有用的 需要記憶的內容寫下 方便日後回顧 CSS語法 選擇符{屬性:屬性值;} ## 所有的css代碼 都要放在css樣式表裡面 1:內部樣式表 在head裡面添加 style標簽 2:外部樣式表 連接外部樣式表 <link rel="stylesheet" h ...
  • JavaScript歷史 它最初由Netscape的Brendan Eich設計。JavaScript是甲骨文公司的註冊商標。Ecma國際以JavaScript為基礎制定了ECMAScript標準。JavaScript也可以用於其他場合,如伺服器端編程。完整的JavaScript實現包含三個部分:E ...
  • 1、場景使用windows的360瀏覽器打開網頁白屏使用mac 谷歌,360,火狐瀏覽器打開均正常2、原因 windows瀏覽器預設使用的是ie瀏覽器內核渲染的,js執行時發生錯誤 3、添加header頭選擇渲染的瀏覽器內核:極速如果你手動設置該網站的瀏覽器內核為IE,360瀏覽器下次訪問該網站時依... ...
一周排行
    -Advertisement-
    Play Games
  • 概述:本文代碼示例演示瞭如何在WPF中使用LiveCharts庫創建動態條形圖。通過創建數據模型、ViewModel和在XAML中使用`CartesianChart`控制項,你可以輕鬆實現圖表的數據綁定和動態更新。我將通過清晰的步驟指南包括詳細的中文註釋,幫助你快速理解並應用這一功能。 先上效果: 在 ...
  • openGauss(GaussDB ) openGauss是一款全面友好開放,攜手伙伴共同打造的企業級開源關係型資料庫。openGauss採用木蘭寬鬆許可證v2發行,提供面向多核架構的極致性能、全鏈路的業務、數據安全、基於AI的調優和高效運維的能力。openGauss深度融合華為在資料庫領域多年的研 ...
  • openGauss(GaussDB ) openGauss是一款全面友好開放,攜手伙伴共同打造的企業級開源關係型資料庫。openGauss採用木蘭寬鬆許可證v2發行,提供面向多核架構的極致性能、全鏈路的業務、數據安全、基於AI的調優和高效運維的能力。openGauss深度融合華為在資料庫領域多年的研 ...
  • 概述:本示例演示了在WPF應用程式中實現多語言支持的詳細步驟。通過資源字典和數據綁定,以及使用語言管理器類,應用程式能夠在運行時動態切換語言。這種方法使得多語言支持更加靈活,便於維護,同時提供清晰的代碼結構。 在WPF中實現多語言的一種常見方法是使用資源字典和數據綁定。以下是一個詳細的步驟和示例源代 ...
  • 描述(做一個簡單的記錄): 事件(event)的本質是一個委托;(聲明一個事件: public event TestDelegate eventTest;) 委托(delegate)可以理解為一個符合某種簽名的方法類型;比如:TestDelegate委托的返回數據類型為string,參數為 int和 ...
  • 1、AOT適合場景 Aot適合工具類型的項目使用,優點禁止反編 ,第一次啟動快,業務型項目或者反射多的項目不適合用AOT AOT更新記錄: 實實在在經過實踐的AOT ORM 5.1.4.117 +支持AOT 5.1.4.123 +支持CodeFirst和非同步方法 5.1.4.129-preview1 ...
  • 總說周知,UWP 是運行在沙盒裡面的,所有許可權都有嚴格限制,和沙盒外交互也需要特殊的通道,所以從根本杜絕了 UWP 毒瘤的存在。但是實際上 UWP 只是一個應用模型,本身是沒有什麼許可權管理的,許可權管理全靠 App Container 沙盒控制,如果我們脫離了這個沙盒,UWP 就會放飛自我了。那麼有沒... ...
  • 目錄條款17:讓介面容易被正確使用,不易被誤用(Make interfaces easy to use correctly and hard to use incorrectly)限制類型和值規定能做和不能做的事提供行為一致的介面條款19:設計class猶如設計type(Treat class de ...
  • title: 從零開始:Django項目的創建與配置指南 date: 2024/5/2 18:29:33 updated: 2024/5/2 18:29:33 categories: 後端開發 tags: Django WebDev Python ORM Security Deployment Op ...
  • 1、BOM對象 BOM:Broswer object model,即瀏覽器提供我們開發者在javascript用於操作瀏覽器的對象。 1.1、window對象 視窗方法 // BOM Browser object model 瀏覽器對象模型 // js中最大的一個對象.整個瀏覽器視窗出現的所有東西都 ...