MJingv / jehol-person-blog

Jehol's Blog 🙋 (hexo+react)
https://mjingv.github.io/JeholBlog/
0 stars 1 forks source link

手写bind/call/apply/new #22

Open MJingv opened 5 years ago

MJingv commented 5 years ago

bind、call、apply 、new 改变this最后一遍

手写bind


Function.prototype.mybind = function (ctx, ...res) {
    return () => {
        this.call(ctx, res);
    };

};

// Function.prototype.mybind = function (ctx, ...res) {
//  let self = this;
//  return function () {
//      self.call(ctx, res);
//  };
//
// };

function sayname(arg) {
    console.log(this.name, 'arg', ...arg);
}

let obj = {
    name: 'jehol'
};

sayname.mybind(obj, '我是参数')();

Function.prototype.mybind = function (ctx, ...res) { // ctx = ctx || window; ctx.foo = this; return () => { ctx.foo(res); delete ctx.foo; };

console.log(ctx);

};

function sayname(arg) { console.log(this.name, '---arg---', arg); }

let obj = { name: 'jehol' };

sayname.mybind(obj, '我是参数')();


手写call / apply
---

- 给传入ctx新属性(本函数)=》执行=》删除此属性

```js

Function.prototype.mycall = function (ctx, ...res) {
    // ctx = ctx || window;
    ctx.foo = this;
    ctx.foo(res);
    delete ctx.foo;
    console.log(ctx);
};

function sayname(arg) {
    console.log(this.name, '---arg---', arg);//apply
    //console.log(this.name, '---arg---', ...arg);//call

}

let obj = {
    name: 'jehol'
};

sayname.mycall(obj, '我是参数');

手写new【有问题】

function Foo(...arg) { this.name = arg[0]; this.age = arg[1]; }

Foo.prototype.sayname = function () { console.log(this.name); }; Foo.prototype.sex = 'fe';

function Create(Foo, ...arg) { let obj = {}; obj.name = arg[0]; obj.proto = Foo.prototype; return obj; }

let f = Create(Foo, 'jehol');

f.sayname(); console.log(f.sex)

更新手写new
---
```js

function myNew(Foo, ...rest) {
    let obj = {};
    obj.__proto__ = Foo.prototype;
    FOO.call(obj, ...rest);
    return obj;
}

function FOO(name, age) {
    this.name = name;
    this.age = age;
}
let f = myNew(FOO, 'jehol', 23);
console.log(f.name, f.age);
MJingv commented 4 years ago

new

function newOperator(ctor, ...args) {
    if(typeof ctor !== 'function'){
      throw 'newOperator function the first param must be a function';
    }
    let obj = Object.create(ctor.prototype);
    let res = ctor.apply(obj, args);

    let isObject = typeof res === 'object' && res !== null;
    let isFunction = typoof res === 'function';
    return isObect || isFunction ? res : obj;
};