原型链

发表于:2023-07-17 18:49技术,面试题热度:14喜欢:0

手写new

function Dog(name){
    this.name = name;
}

Dog.prototype.bark = function (){
    console.log('wangwang')
}
Dog.prototype.sayName = function (){
    console.log(`my name is ${this.name}`)
}
function _new(Func,...agrs){
    //entery you code 
}

let sanmao = _new(Dog,'三毛')
sanmao.bark();//wangwang
sanmao.sayName();//my name is 三毛

console.log(sanmao instanceof Dog) //true
//实例对象.__proto__ = Dog.prototype
//把函数执行
//this 实例对象

function _new(Func,...args){
    //创建实例对象
    let obj = {};
    obj.__proto__ = Func.prototype
    //let obj = Object.create(Func.prototype)
    //把方法执行,改变this
    let result = Func.call(obj,...agrs);
    //3.分析返回结果
    if(result!==null&&/^(object|function)$/.test(typeof result)) return result
    return obj;
}

手写call

~function (){
    function change(context,...args){
        //this -> func

        //判断是否有上下文
        context = context===undefined?window:context;
        if( !/^(object|function)$/.test(typeof context)){
            //把非对象类型转换成对象
            //这两种 没有constructor
            if(^/(symbol|bigint)$/.text(typeof context)){
                context = Object(context)
            }else{
                //context = new 'abc'.constructor('abc');
                context =  new context.constructor(context)
            }

        }
        //设置一个唯一的key,
        let key = Symbol('key');//假设为一个方法change
        let result;
        context[key] = this;

        //obj[change]= func;
        //obj.change = func;
        //obj.change(...args)

        result = context[key](...args);

        delete context[key];
        return result;
    }
    Function.prototype.change = change;
}()
let obj = {name:'NNNNzs'}
function func (x,y){
    this.totle = x + y ;
    return this;
}
let res = func.change(obj,100,200)
console.log(res);
//{name:'zhufeng',total:300}

手写bind

~function (){
    // this 是func
    function mybind(context,...args){
        //判断是否有上下文
        let _this = this;
        context = context===undefined?window:context;
        if( !/^(object|function)$/.test(typeof context)){
            //把非对象类型转换成对象
            //这两种 没有constructor
            if(^/(symbol|bigint)$/.text(typeof context)){
                context = Object(context)
            }else{
                //context = new 'abc'.constructor('abc');
                context =  new context.constructor(context)
            }

        }
        return function anonymous (...innerArgs){
            _this.call(context,...args.concat(innerArgs))
        }
    }
    Function.prototype.mybind = mybind
}();
var obj = {
    name:'NNNNzs'
}
function func(){
    console.log(this,arguments);
    
}
document.body.onclick = func.mybind(obj,10,20)