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.深度學習是機器學習的...