我要懂系列1 call和apply

2021-09-14 05:42:42 字數 2875 閱讀 8212

fn.call(isthis, arg1, arg2, ....)

相同點:

改變 this 指向

可以傳參

立即呼叫

區別:模擬實現:

function.prototype.calllike = function (isthis) 

//...

}

傳遞的 isthis 如果是 undefined 或者 null,那麼 this 就是 window,否則傳遞進來的就是要指向的this

call 從第二個引數開始就是要呼叫時用到引數

第乙個條件很簡單,判斷下 isthis 的型別即可

isthis = typeof isthis === 'undefined' || isnull(isthis) ? window : isthis;

function isnull (value)

第二個條件和第三個條件是一樣的,call 的引數我們需要處理下,因為我們預期不到它的引數個數

我們從第二個引數開始遍歷一遍 arguments,然後放到乙個陣列裡面去

var args = ;

for (var i = 1, l = arguments.length; i< l; i++)

但是最關鍵的呼叫怎麼辦呢,怎麼改變 this 的指向,一般來說誰呼叫誰就是 this,我們要想改變 this,那麼就要用傳遞進來的 isthis 來呼叫

isthis.fn = this;

isthis.fn();

delete isthis.fn;

這樣的話就改變了 this 的指向,之後再 delete 掉,就 ok 了,但是這裡會有乙個問題,如果傳遞進來的是值型別呢,值型別我們是不能給它新增屬性和方法的,所以isthis.fn()肯定會提示isthis.fn is not a function,這裡我們可以想一想值型別也是可以像物件一樣有屬性和方法的,並且可以新增屬性和方法,但是為什麼賦值完後就找不到呢

這裡要說下包裝型別了,值型別按理說是不可能有自己的屬性和方法的,但是考慮到有時候需要處理下雜七雜八的瑣事,所以當我們訪問或者賦值的時候,它會臨時給我們建立乙個對應的包裝物件,在我們訪問或者賦值結束後那麼這個包裝物件就會被清理掉,那麼我們就可以這樣做,來模擬下包裝物件

var valuetype = typeof isthis;

if (valuetype === 'string') else if (valuetype === 'number') else if (valuetype === 'boolean') else if (valuetype === 'symbol')

恩,這樣一來就差不多了,接下來看看傳參,args 的元素才是我們想要的引數,所以怎麼拆開

var result = eval('isthis.fn(' + args.join() + ')');
使用 eval,得益於 eval 強大的能力,我們可以把字串當做 js **來執行,並且可以得到返回值,完美

但是這裡會有乙個問題,如果引數是個物件,那麼 eval 對引數 tostring 後我們我們就得不到想要的引數了,所以這裡改造下,因為 eval 可以動態的改變作用域

var args = ;

for (var i = 1, l = arguments.length; i< l; i++)

var result = eval('isthis.fn(' + args.join() + ')');

這裡我們用 args 存放著 arguments[1] arguments[1]... 這樣的字串,那麼 eval 執行的時候會在上下文查詢並繫結所需要的變數,這樣就可以實現引數傳遞了

完整**:

function.prototype.calllike = function (isthis) else if (valuetype === 'number') else if (valuetype === 'boolean') else if (valuetype === 'symbol') 

isthis.fn = this;

var args = ;

for (var i = 1, l = arguments.length; i< l; i++)

var result = eval('isthis.fn(' + args.join() + ')');

delete isthis.fn;

function isnull (value)

return result;

}

isthis = typeof isthis === 'undefined' || isnull(isthis) ? window : isthis;

var valuetype = typeof isthis;

if (valuetype === 'string') else if (valuetype === 'number') else if (valuetype === 'boolean') else if (valuetype === 'symbol')

isthis.fn = this;

var args = ;

for (var i = 1, l = arguments.length; i< l; i++)

var result = eval('isthis.fn(' + args.join() + ')');

delete isthis.fn;

function isnull (value)

return result;}

我要挖坑了系列 模板合集

嗨咻 挖個大坑 已填坑 14 50 2019.07.27 字串名詞介紹 kmp 擴充套件kmp manacher ac自動機 待填 字尾陣列 待填 字尾自動機 待填 字串hash 待填 認識基本object 點 線 面 交點 面積的計算 對稱 平移和旋轉 待填 三角形與圓 待填 最小圓覆蓋 待填 卷...

資料倉儲系列(1) 為什麼要搭建資料倉儲

本文寫作的初衷,是想以阿里巴巴的onedata體系為出發點,詳細闡述資料倉儲搭建的初衷 架構的理念及實現的方式,藉此來總結從事大資料開發崗位多年以來的經驗積累。僅從筆者個人角度出發,收集相關素材,進行二次整理,並非原創。要想全面的來看待資料倉儲,首先要回答的是資料倉儲搭建的目的 筆者個人理解 以資料...

我自學系列的第1講之機器學習概述

1 人工智慧概述 1.1 人工智慧起源 1.圖靈測試 2.達特茅斯會議 1.2 人工智慧三個階段 1.1980年代是正式形成期 2.1990 2010年代是蓬勃發展期 3.2012年之後是深度學習期 1.3 人工智慧 機器學習和深度學習 1.機器學習是人工智慧的乙個實現途徑 2.深度學習是機器學習的...