diff --git a/JavaScript_Sea/apply&call.ts b/JavaScript_Sea/apply&call.ts new file mode 100644 index 0000000..e189504 --- /dev/null +++ b/JavaScript_Sea/apply&call.ts @@ -0,0 +1,60 @@ +/** + * @description 模拟 apply&call + * @date 2022-07-01 + * @article https://zhuanlan.zhihu.com/p/51259309 + */ + +function getGlobalObject() { + return this; +} + +(Function as any).prototype.myApply = function apply( + thisArg = getGlobalObject(), + argsArray = [] +) { + if (typeof this !== "function") { + throw new TypeError(this + " is not a function"); + } + + if (argsArray !== new Object(argsArray)) { + throw new TypeError("CreateListFromArrayLike called on non-object"); + } + + if (thisArg == null) thisArg = getGlobalObject(); + if (argsArray == null) argsArray = []; + + thisArg = new Object(thisArg); + thisArg["__fn"] = this; + const result = thisArg["__fn"](...argsArray); + delete thisArg["__fn"]; + + return result; +}; + +// 额外情况 +// 1. 如果 thisArg 中已经存在一个同名 __fn 属性呢? +// 2. 解决以上问题不允许使用 Sybmol + +(Function as any).prototype.myCall = function call(thisArg) { + const argsArray: any[] = []; + for (let index = 1; index <= arguments.length - 1; index++) { + argsArray[index - 1] = arguments[index]; + } + + return this.myApply(thisArg, argsArray); +}; + +const testObj = { + name: "Hello", + child: 200, + index: 0, +}; + +function tsetFunction(...args) { + console.log("value", args); + console.log("name", this.name); + console.log("child", this.child); + console.log("index", this.index); +} + +(tsetFunction as any).myCall(testObj, 100, 200, 300, 400, 500, 600, 700); diff --git a/JavaScript_Sea/bind.ts b/JavaScript_Sea/bind.ts new file mode 100644 index 0000000..66a6d98 --- /dev/null +++ b/JavaScript_Sea/bind.ts @@ -0,0 +1,27 @@ +/** + * @description 模拟 bind + * @date 2022-06-30 + * @article https://zhuanlan.zhihu.com/p/50539121 + */ + +(Function as any).prototype.myBind = function myBind(newThis, ...args) { + // 下边会用到该作用域的 this,所以这里需要保存 this 的指向 + const self = this; + const bindFunction = function (...argss) { + return self.apply(newThis, [...args, ...argss]); + }; + + return bindFunction; +}; + +const obj = { + name: "myBind", +}; + +function original(a, b) { + console.log(this.name); + console.log([a, b]); +} + +const bound = (original as any).myBind(obj, 1); +bound(2); diff --git a/JavaScript_Sea/new.ts b/JavaScript_Sea/new.ts index f62064e..813d184 100644 --- a/JavaScript_Sea/new.ts +++ b/JavaScript_Sea/new.ts @@ -1,6 +1,7 @@ /** * @description 模拟 new * @date 2022-06-29 + * @article https://zhuanlan.zhihu.com/p/50719681 */ function Op1(name, age) {