成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

面試官問:能否模擬實現(xiàn)JS的call和apply方法

wuyangnju / 3174人閱讀

摘要:之前寫過兩篇面試官問能否模擬實現(xiàn)的操作符和面試官問能否模擬實現(xiàn)的方法其中模擬方法時是使用的和修改指向。但面試官可能問能否不用和來實現(xiàn)呢。使用模擬實現(xiàn)的瀏覽器環(huán)境非嚴格模式方法的屬性是。

之前寫過兩篇《面試官問:能否模擬實現(xiàn)JSnew操作符》和《面試官問:能否模擬實現(xiàn)JSbind方法》

其中模擬bind方法時是使用的callapply修改this指向。但面試官可能問:能否不用callapply來實現(xiàn)呢。意思也就是需要模擬實現(xiàn)callapply的了。

附上之前寫文章寫過的一段話:已經(jīng)有很多模擬實現(xiàn)callapply的文章,為什么自己還要寫一遍呢。學(xué)習(xí)就好比是座大山,人們沿著不同的路登山,分享著自己看到的風(fēng)景。你不一定能看到別人看到的風(fēng)景,體會到別人的心情。只有自己去登山,才能看到不一樣的風(fēng)景,體會才更加深刻。
先通過MDN認識下callapply

MDN 文檔:Function.prototype.call()

語法

fun.call(thisArg, arg1, arg2, ...)

thisArg

fun函數(shù)運行時指定的this值。需要注意的是,指定的this值并不一定是該函數(shù)執(zhí)行時真正的this值,如果這個函數(shù)處于非嚴格模式下,則指定為nullundefinedthis值會自動指向全局對象(瀏覽器中就是window對象),同時值為原始值(數(shù)字,字符串,布爾值)的this會指向該原始值的自動包裝對象。

arg1, arg2, ...

指定的參數(shù)列表

返回值

返回值是你調(diào)用的方法的返回值,若該方法沒有返回值,則返回undefined。

MDN 文檔:Function.prototype.apply()

func.apply(thisArg, [argsArray])

thisArg

可選的。在 func 函數(shù)運行時使用的 this 值。請注意,this可能不是該方法看到的實際值:如果這個函數(shù)處于非嚴格模式下,則指定為 nullundefined 時會自動替換為指向全局對象,原始值會被包裝。

argsArray

可選的。一個數(shù)組或者類數(shù)組對象,其中的數(shù)組元素將作為多帶帶的參數(shù)傳給 func 函數(shù)。如果該參數(shù)的值為 nullundefined,則表示不需要傳入任何參數(shù)。從ECMAScript 5 開始可以使用類數(shù)組對象。

返回值

調(diào)用有指定this值和參數(shù)的函數(shù)的結(jié)果。
直接先看例子1

callapply 的異同

相同點:

1、callapply的第一個參數(shù)thisArg,都是func運行時指定的this。而且,this可能不是該方法看到的實際值:如果這個函數(shù)處于非嚴格模式下,則指定為 nullundefined 時會自動替換為指向全局對象,原始值會被包裝。

2、都可以只傳遞一個參數(shù)。

不同點:apply只接收兩個參數(shù),第二個參數(shù)可以是數(shù)組也可以是類數(shù)組,其實也可以是對象,后續(xù)的參數(shù)忽略不計。call接收第二個及以后一系列的參數(shù)。

看兩個簡單例子1和2**:

// 例子1:瀏覽器環(huán)境 非嚴格模式下
var doSth = function(a, b){
    console.log(this);
    console.log([a, b]);
}
doSth.apply(null, [1, 2]); // this是window  // [1, 2]
doSth.apply(0, [1, 2]); // this 是 Number(0) // [1, 2]
doSth.apply(true); // this 是 Boolean(true) // [undefined, undefined]
doSth.call(undefined, 1, 2); // this 是 window // [1, 2]
doSth.call("0", 1, {a: 1}); // this 是 String("0") // [1, {a: 1}]
// 例子2:瀏覽器環(huán)境 嚴格模式下
"use strict";
var doSth2 = function(a, b){
    console.log(this);
    console.log([a, b]);
}
doSth2.call(0, 1, 2); // this 是 0 // [1, 2]
doSth2.apply("1"); // this 是 "1" // [undefined, undefined]
doSth2.apply(null, [1, 2]); // this 是 null // [1, 2]

typeof7種類型(undefined number string boolean symbol object function),筆者都驗證了一遍:更加驗證了相同點第一點,嚴格模式下,函數(shù)的this值就是callapply的第一個參數(shù)thisArg,非嚴格模式下,thisArg值被指定為 nullundefinedthis值會自動替換為指向全局對象,原始值則會被自動包裝,也就是new Object()

重新認識了callapply會發(fā)現(xiàn):它們作用都是一樣的,改變函數(shù)里的this指向為第一個參數(shù)thisArg,如果明確有多少參數(shù),那可以用call,不明確則可以使用apply。也就是說完全可以不使用call,而使用apply代替。

也就是說,我們只需要模擬實現(xiàn)apply,call可以根據(jù)參數(shù)個數(shù)都放在一個數(shù)組中,給到apply即可。

模擬實現(xiàn) apply

既然準備模擬實現(xiàn)apply,那先得看看ES5規(guī)范。ES5規(guī)范 英文版ES5規(guī)范 中文版。apply的規(guī)范下一個就是call的規(guī)范,可以點擊打開新標簽頁去查看,這里摘抄一部分。

Function.prototype.apply (thisArg, argArray)

當以 thisArgargArray 為參數(shù)在一個 func 對象上調(diào)用 apply 方法,采用如下步驟:

1.如果 IsCallable(func)false, 則拋出一個 TypeError 異常。

2.如果 argArraynullundefined, 則返回提供 thisArg 作為 this 值并以空參數(shù)列表調(diào)用 func[[Call]] 內(nèi)部方法的結(jié)果。

3.返回提供 thisArg 作為 this 值并以空參數(shù)列表調(diào)用 func[[Call]] 內(nèi)部方法的結(jié)果。

4.如果 Type(argArray) 不是 Object, 則拋出一個 TypeError 異常。

5~8 略

9.提供 thisArg 作為 this 值并以 argList 作為參數(shù)列表,調(diào)用 func[[Call]] 內(nèi)部方法,返回結(jié)果。

apply 方法的 length 屬性是 2。

在外面?zhèn)魅氲?thisArg 值會修改并成為 this 值。thisArgundefinednull 時它會被替換成全局對象,所有其他值會被應(yīng)用 ToObject 并將結(jié)果作為 this 值,這是第三版引入的更改。

結(jié)合上文和規(guī)范,如何將函數(shù)里的this指向第一個參數(shù)thisArg呢,這是一個問題。
這時候請出例子3

// 瀏覽器環(huán)境 非嚴格模式下
var doSth = function(a, b){
    console.log(this);
    console.log(this.name);
    console.log([a, b]);
}
var student = {
    name: "軒轅Rowboat",
    doSth: doSth,
};
student.doSth(1, 2); // this === student // true // "軒轅Rowboat" // [1, 2]
doSth.apply(student, [1, 2]); // this === student // true // "軒轅Rowboat" // [1, 2]

可以得出結(jié)論1:在對象student上加一個函數(shù)doSth,再執(zhí)行這個函數(shù),這個函數(shù)里的this就指向了這個對象。那也就是可以在thisArg上新增調(diào)用函數(shù),執(zhí)行后刪除這個函數(shù)即可。
知道這些后,我們試著容易實現(xiàn)第一版本:

// 瀏覽器環(huán)境 非嚴格模式
function getGlobalObject(){
    return this;
}
Function.prototype.applyFn = function apply(thisArg, argsArray){ // `apply` 方法的 `length` 屬性是 `2`。
    // 1.如果 `IsCallable(func)` 是 `false`, 則拋出一個 `TypeError` 異常。
    if(typeof this !== "function"){
        throw new TypeError(this + " is not a function");
    }

    // 2.如果 argArray 是 null 或 undefined, 則
    // 返回提供 thisArg 作為 this 值并以空參數(shù)列表調(diào)用 func 的 [[Call]] 內(nèi)部方法的結(jié)果。
    if(typeof argsArray === "undefined" || argsArray === null){
        argsArray = [];
    }
    
    // 3.如果 Type(argArray) 不是 Object, 則拋出一個 TypeError 異常 .
    if(argsArray !== new Object(argsArray)){
        throw new TypeError("CreateListFromArrayLike called on non-object");
    }

    if(typeof thisArg === "undefined" || thisArg === null){
        // 在外面?zhèn)魅氲?thisArg 值會修改并成為 this 值。
        // ES3: thisArg 是 undefined 或 null 時它會被替換成全局對象 瀏覽器里是window
        thisArg = getGlobalObject();
    }

    // ES3: 所有其他值會被應(yīng)用 ToObject 并將結(jié)果作為 this 值,這是第三版引入的更改。
    thisArg = new Object(thisArg);
    var __fn = "__fn";
    thisArg[__fn] = this;
    // 9.提供 thisArg 作為 this 值并以 argList 作為參數(shù)列表,調(diào)用 func 的 [[Call]] 內(nèi)部方法,返回結(jié)果
    var result = thisArg[__fn](...argsArray);
    delete thisArg[__fn];
    return result;
};
實現(xiàn)第一版后,很容易找出兩個問題:

[ ] 1.__fn 同名覆蓋問題,thisArg對象上有__fn,那就被覆蓋了然后被刪除了。

針對問題1
解決方案一:采用ES6 Sybmol() 獨一無二的??梢员緛砭褪悄MES3的方法。如果面試官不允許用呢。
解決方案二:自己用Math.random()模擬實現(xiàn)獨一無二的key。面試時可以直接用生成時間戳即可。

// 生成UUID 通用唯一識別碼
// 大概生成 這樣一串 "18efca2d-6e25-42bf-a636-30b8f9f2de09"
function generateUUID(){
    var i, random;
    var uuid = "";
    for (i = 0; i < 32; i++) {
        random = Math.random() * 16 | 0;
        if (i === 8 || i === 12 || i === 16 || i === 20) {
            uuid += "-";
        }
        uuid += (i === 12 ? 4 : (i === 16 ? (random & 3 | 8) : random))
            .toString(16);
    }
    return uuid;
}
// 簡單實現(xiàn)
// "__" + new Date().getTime();

如果這個key萬一這對象中還是有,為了保險起見,可以做一次緩存操作。比如如下代碼:

var student = {
    name: "軒轅Rowboat",
    doSth: "doSth",
};
var originalVal = student.doSth;
var hasOriginalVal = student.hasOwnProperty("doSth");
student.doSth = function(){};
delete student.doSth;
// 如果沒有,`originalVal`則為undefined,直接賦值新增了一個undefined,這是不對的,所以需判斷一下。
if(hasOriginalVal){
    student.doSth = originalVal;
}
console.log("student:", student); // { name: "軒轅Rowboat", doSth: "doSth" }

[ ] 2.使用了ES6擴展符...

解決方案一:采用eval來執(zhí)行函數(shù)。

eval把字符串解析成代碼執(zhí)行。

MDN 文檔:eval

語法
eval(string)

參數(shù)

string

表示JavaScript表達式,語句或一系列語句的字符串。表達式可以包含變量以及已存在對象的屬性。

返回值

執(zhí)行指定代碼之后的返回值。如果返回值為空,返回undefined

解決方案二:但萬一面試官不允許用eval呢,畢竟eval是魔鬼??梢圆捎?b>new Function()來生成執(zhí)行函數(shù)。
MDN 文檔:Function

語法

new Function ([arg1[, arg2[, ...argN]],] functionBody)

參數(shù)

arg1, arg2, ... argN

被函數(shù)使用的參數(shù)的名稱必須是合法命名的。參數(shù)名稱是一個有效的JavaScript標識符的字符串,或者一個用逗號分隔的有效字符串的列表;例如“×”,“theValue”,或“A,B”。

functionBody

一個含有包括函數(shù)定義的JavaScript語句的字符串。

接下來看兩個例子:

簡單例子:
var sum = new Function("a", "b", "return a + b");
console.log(sum(2, 6));
// 稍微復(fù)雜點的例子:
var student = {
    name: "軒轅Rowboat",
    doSth: function(argsArray){
        console.log(argsArray);
        console.log(this.name);
    }
};
// var result = student.doSth(["Rowboat", 18]);
// 用new Function()生成函數(shù)并執(zhí)行返回結(jié)果
var result = new Function("return arguments[0][arguments[1]](arguments[2][0], arguments[2][1])")(student, "doSth", ["Rowboat", 18]);
// 個數(shù)不定
// 所以可以寫一個函數(shù)生成函數(shù)代碼:
function generateFunctionCode(argsArrayLength){
    var code = "return arguments[0][arguments[1]](";
    for(var i = 0; i < argsArrayLength; i++){
        if(i > 0){
            code += ",";
        }
        code += "arguments[2][" + i + "]";
    }
    code += ")";
    // return arguments[0][arguments[1]](arg1, arg2, arg3...)
    return code;
}
你可能不知道在ES3、ES5undefined 是能修改的

可能大部分人不知道。ES5中雖然在全局作用域下不能修改,但在局部作用域中也是能修改的,不信可以復(fù)制以下測試代碼在控制臺執(zhí)行下。雖然一般情況下是不會的去修改它。

function test(){
    var undefined = 3;
    console.log(undefined); // chrome下也是 3
}
test();

所以判斷一個變量a是不是undefined,更嚴謹?shù)姆桨甘?b>typeof a === "undefined"或者a === void 0;
這里面用的是void,void的作用是計算表達式,始終返回undefined,也可以這樣寫void(0)。
更多可以查看韓子遲的這篇文章:為什么用「void 0」代替「undefined」
解決了這幾個問題,比較容易實現(xiàn)如下代碼。

使用 new Function() 模擬實現(xiàn)的apply
// 瀏覽器環(huán)境 非嚴格模式
function getGlobalObject(){
    return this;
}
function generateFunctionCode(argsArrayLength){
    var code = "return arguments[0][arguments[1]](";
    for(var i = 0; i < argsArrayLength; i++){
        if(i > 0){
            code += ",";
        }
        code += "arguments[2][" + i + "]";
    }
    code += ")";
    // return arguments[0][arguments[1]](arg1, arg2, arg3...)
    return code;
}
Function.prototype.applyFn = function apply(thisArg, argsArray){ // `apply` 方法的 `length` 屬性是 `2`。
    // 1.如果 `IsCallable(func)` 是 `false`, 則拋出一個 `TypeError` 異常。
    if(typeof this !== "function"){
        throw new TypeError(this + " is not a function");
    }
    // 2.如果 argArray 是 null 或 undefined, 則
    // 返回提供 thisArg 作為 this 值并以空參數(shù)列表調(diào)用 func 的 [[Call]] 內(nèi)部方法的結(jié)果。
    if(typeof argsArray === "undefined" || argsArray === null){
        argsArray = [];
    }
    // 3.如果 Type(argArray) 不是 Object, 則拋出一個 TypeError 異常 .
    if(argsArray !== new Object(argsArray)){
        throw new TypeError("CreateListFromArrayLike called on non-object");
    }
    if(typeof thisArg === "undefined" || thisArg === null){
        // 在外面?zhèn)魅氲?thisArg 值會修改并成為 this 值。
        // ES3: thisArg 是 undefined 或 null 時它會被替換成全局對象 瀏覽器里是window
        thisArg = getGlobalObject();
    }
    // ES3: 所有其他值會被應(yīng)用 ToObject 并將結(jié)果作為 this 值,這是第三版引入的更改。
    thisArg = new Object(thisArg);
    var __fn = "__" + new Date().getTime();
    // 萬一還是有 先存儲一份,刪除后,再恢復(fù)該值
    var originalVal = thisArg[__fn];
    // 是否有原始值
    var hasOriginalVal = thisArg.hasOwnProperty(__fn);
    thisArg[__fn] = this;
    // 9.提供 `thisArg` 作為 `this` 值并以 `argList` 作為參數(shù)列表,調(diào)用 `func` 的 `[[Call]]` 內(nèi)部方法,返回結(jié)果。
    // ES6版
    // var result = thisArg[__fn](...args);
    var code = generateFunctionCode(argsArray.length);
    var result = (new Function(code))(thisArg, __fn, argsArray);
    delete thisArg[__fn];
    if(hasOriginalVal){
        thisArg[__fn] = originalVal;
    }
    return result;
};
利用模擬實現(xiàn)的apply模擬實現(xiàn)call
Function.prototype.callFn = function call(thisArg){
    var argsArray = [];
    var argumentsLength = arguments.length;
    for(var i = 0; i < argumentsLength - 1; i++){
        // argsArray.push(arguments[i + 1]);
        argsArray[i] = arguments[i + 1];
    }
    console.log("argsArray:", argsArray);
    return this.applyFn(thisArg, argsArray);
}
// 測試例子
var doSth = function (name, age){
    var type = Object.prototype.toString.call(this);
    console.log(typeof doSth);
    console.log(this === firstArg);
    console.log("type:", type);
    console.log("this:", this);
    console.log("args:", [name, age], arguments);
    return "this--";
};

var name = "window";

var student = {
    name: "軒轅Rowboat",
    age: 18,
    doSth: "doSth",
    __fn: "doSth",
};
var firstArg = student;
var result = doSth.applyFn(firstArg, [1, {name: "Rowboat"}]);
var result2 = doSth.callFn(firstArg, 1, {name: "Rowboat"});
console.log("result:", result);
console.log("result2:", result2);

細心的你會發(fā)現(xiàn)注釋了這一句argsArray.push(arguments[i + 1]);,事實上push方法,內(nèi)部也有一層循環(huán)。所以理論上不使用push性能會更好些。面試官也可能根據(jù)這點來問時間復(fù)雜度和空間復(fù)雜度的問題。

// 看看V8引擎中的具體實現(xiàn):
function ArrayPush() {
    var n = TO_UINT32( this.length );    // 被push的對象的length
    var m = %_ArgumentsLength();     // push的參數(shù)個數(shù)
    for (var i = 0; i < m; i++) {
        this[ i + n ] = %_Arguments( i );   // 復(fù)制元素     (1)
    }
    this.length = n + m;      // 修正length屬性的值    (2)
    return this.length;
};

行文至此,就基本結(jié)束了,你可能還發(fā)現(xiàn)就是寫的非嚴格模式下,thisArg原始值會包裝成對象,添加函數(shù)并執(zhí)行,再刪除。而嚴格模式下還是原始值這個沒有實現(xiàn),而且萬一這個對象是凍結(jié)對象呢,Object.freeze({}),是無法在這個對象上添加屬性的。所以這個方法只能算是非嚴格模式下的簡版實現(xiàn)。最后來總結(jié)一下。

總結(jié)

通過MDN認識callapply,閱讀ES5規(guī)范,到模擬實現(xiàn)apply,再實現(xiàn)call。

就是使用在對象上添加調(diào)用apply的函數(shù)執(zhí)行,這時的調(diào)用函數(shù)的this就指向了這個thisArg,再返回結(jié)果。引出了ES6 Symbol,ES6的擴展符...eval、new Function(),嚴格模式等。

事實上,現(xiàn)實業(yè)務(wù)場景不需要去模擬實現(xiàn)callapply,畢竟是ES3就提供的方法。但面試官可以通過這個面試題考察候選人很多基礎(chǔ)知識。如:call、apply的使用。ES6 Symbol,ES6的擴展符...eval,new Function(),嚴格模式,甚至?xí)r間復(fù)雜度和空間復(fù)雜度等。

讀者發(fā)現(xiàn)有不妥或可改善之處,歡迎指出。另外覺得寫得不錯,可以點個贊,也是對筆者的一種支持。

// 最終版版 刪除注釋版,詳細注釋看文章
// 瀏覽器環(huán)境 非嚴格模式
function getGlobalObject(){
    return this;
}
function generateFunctionCode(argsArrayLength){
    var code = "return arguments[0][arguments[1]](";
    for(var i = 0; i < argsArrayLength; i++){
        if(i > 0){
            code += ",";
        }
        code += "arguments[2][" + i + "]";
    }
    code += ")";
    return code;
}
Function.prototype.applyFn = function apply(thisArg, argsArray){
    if(typeof this !== "function"){
        throw new TypeError(this + " is not a function");
    }
    if(typeof argsArray === "undefined" || argsArray === null){
        argsArray = [];
    }
    if(argsArray !== new Object(argsArray)){
        throw new TypeError("CreateListFromArrayLike called on non-object");
    }
    if(typeof thisArg === "undefined" || thisArg === null){
        thisArg = getGlobalObject();
    }
    thisArg = new Object(thisArg);
    var __fn = "__" + new Date().getTime();
    var originalVal = thisArg[__fn];
    var hasOriginalVal = thisArg.hasOwnProperty(__fn);
    thisArg[__fn] = this;
    var code = generateFunctionCode(argsArray.length);
    var result = (new Function(code))(thisArg, __fn, argsArray);
    delete thisArg[__fn];
    if(hasOriginalVal){
        thisArg[__fn] = originalVal;
    }
    return result;
};
Function.prototype.callFn = function call(thisArg){
    var argsArray = [];
    var argumentsLength = arguments.length;
    for(var i = 0; i < argumentsLength - 1; i++){
        argsArray[i] = arguments[i + 1];
    }
    return this.applyFn(thisArg, argsArray);
}
擴展閱讀

《JavaScript設(shè)計模式與開發(fā)實踐》- 第二章 第 2 章 this、call和apply
JS魔法堂:再次認識Function.prototype.call
不用call和apply方法模擬實現(xiàn)ES5的bind方法
JavaScript深入之call和apply的模擬實現(xiàn)

關(guān)于

作者:常以軒轅Rowboat若川為名混跡于江湖。前端路上 | PPT愛好者 | 所知甚少,唯善學(xué)。
個人博客
segmentfault前端視野專欄,開通了前端視野專欄,歡迎關(guān)注
掘金專欄,歡迎關(guān)注
知乎前端視野專欄,開通了前端視野專欄,歡迎關(guān)注
github,歡迎follow~

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/99597.html

相關(guān)文章

  • 面試官問能否模擬實現(xiàn)JSbind方法

    摘要:點擊那么面試官可能會問是否想過到底做了什么,怎么模擬實現(xiàn)呢。另外前不久寫過一篇文章面試官問能否模擬實現(xiàn)的操作符。所以相當于調(diào)用時,的返回值函數(shù)內(nèi)部要模擬實現(xiàn)實現(xiàn)的操作。文章中的例子和測試代碼放在中模擬實現(xiàn)。 前言 用過React的同學(xué)都知道,經(jīng)常會使用bind來綁定this。 import React, { Component } from react; class TodoItem ...

    Julylovin 評論0 收藏0
  • 面試官問JSthis指向

    摘要:之前寫過一篇文章面試官問能否模擬實現(xiàn)的和方法就是利用對象上的函數(shù)指向這個對象,來模擬實現(xiàn)和的。雖然實際使用時不會顯示返回,但面試官會問到。非嚴格模式下,和,指向全局對象 前言 面試官出很多考題,基本都會變著方式來考察this指向,看候選人對JS基礎(chǔ)知識是否扎實。讀者可以先拉到底部看總結(jié),再谷歌(或各技術(shù)平臺)搜索幾篇類似文章,看筆者寫的文章和別人有什么不同(歡迎在評論區(qū)評論不同之處),...

    warnerwu 評論0 收藏0
  • 面試官問能否模擬實現(xiàn)JSnew操作符

    摘要:接下來繼續(xù)看升級版例子例子軒轅軒轅軒轅是瀏覽器實現(xiàn)的查看原型方案。模擬實現(xiàn)知道了這些現(xiàn)象,我們就可以模擬實現(xiàn)操作符。 前言 用過Vuejs的同學(xué)都知道,需要用new操作符來實例化。 new Vue({ el: #app, mounted(){}, }); 那么面試官可能會問是否想過new到底做了什么,怎么模擬實現(xiàn)呢。 附上之前寫文章寫過的一段話:已經(jīng)有很多模擬實現(xiàn)new...

    shenhualong 評論0 收藏0
  • 學(xué)習(xí) underscore 源碼整體架構(gòu),打造屬于自己函數(shù)式編程類庫

    摘要:譯立即執(zhí)行函數(shù)表達式處理支持瀏覽器環(huán)境微信小程序。學(xué)習(xí)整體架構(gòu),利于打造屬于自己的函數(shù)式編程類庫。下一篇文章可能是學(xué)習(xí)的源碼整體架構(gòu)。也可以加微信,注明來源,拉您進前端視野交流群。 前言 上一篇文章寫了jQuery整體架構(gòu),學(xué)習(xí) jQuery 源碼整體架構(gòu),打造屬于自己的 js 類庫 雖然看過挺多underscore.js分析類的文章,但總感覺少點什么。這也許就是紙上得來終覺淺,絕知此...

    junnplus 評論0 收藏0
  • 面試官問JS繼承

    摘要:用過的讀者知道,經(jīng)常用繼承。部分源碼使用點擊這里查看源碼面試官可以順著這個問繼承的相關(guān)問題,比如的繼承用如何實現(xiàn)。主要就是三點子類構(gòu)造函數(shù)的指向父類構(gòu)造器,繼承父類的靜態(tài)方法子類構(gòu)造函數(shù)的的指向父類構(gòu)造器的,繼承父類的方法。 用過React的讀者知道,經(jīng)常用extends繼承React.Component。 // 部分源碼 function Component(props, conte...

    stonezhu 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<