【JavaScript】——4个手撕前端面试题(牛客题库):Object.create、Function.call 、Function.bind、new操作符

1、手写Object.create

要求实现Object.create函数的功能且该新函数命名为"_objectCreate"。

 写代码前,我们先了解Object.create是干什么的

Object.create()方法用于创建一个新对象,使用现有的对象来作为新创建对象的原型(prototype)

语法:obj.create(proto, propertiesObject)

解释:

  proto:表示新创建对象的原型对象。
  propertiesObject:(可选参数)如果该参数被指定且不为 undefined,则该传入对象的自有可枚举属性(即其自身定义的属性,而不是其原型链上的枚举属性)将为新创建的对象添加指定的属性值和对应的属性描述符。这些属性对应于 Object.defineProperties() 的第二个参数。

create() 方法返回一个新一个新对象,带着指定的原型对象及其属性。

完整代码:

const _objectCreate = function (proto, propertiesObject) {
    // 补全代码
    if (typeof proto !== 'object' || proto === null) return;
  	// 定义新对象 
    const obj = {};

    // 设置原型
    // obj.__proto__ = proto // 不建议这么做了
    // 通常,应该使用 Object.setPrototypeOf() 方法来设置对象的原型。
    // 因为 Object.prototype.__proto__ 访问器已被弃用。
    // 建议使用setPrototypeOf设置原型     
    Object.setPrototypeOf(obj, proto) ;
    if (propertiesObject && propertiesObject !== 'undefined') {
    	// 设置属性
        // Object.defineProperties()方法直接在一个对象上定义新的属性或修改现有属性,并返回该对象。
        Object.defineProperties(obj, propertiesObject);
    }

    return obj;
}

2、手写Function.call

要求实现Function.call函数的功能且该新函数命名为"_call"。

 写代码前,我们先了解Function.call是干什么的

Function.call()方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。

语法:fn.call(thisArg,arg1,arg2,...)

解释:

  thisArg:(可选的)表示在 function 函数运行时使用的 this 值。请注意,this可能不是该方法看到的实际值:如果这个函数处于非严格模式下,则指定为 null 或 undefined 时会自动替换为指向全局对象,原始值会被包装。
  arg1,arg2,...:表示指定的参数列表。

filter() 方法返回:使用调用者提供的 this 值和参数调用该函数的返回值。若该方法没有返回值,则返回 undefined

核心步骤有:

  1. 参数默认为window
  2. 获取调用该方法的对象,将this赋给对象参数,可以任意命名
  3. 通过该对象参数临时调用函数并返回结果
  4. 最后删除对象参数的临时函数属性

完整代码:

// target参数默认为window
Function.prototype._call = function (target = window, ...arg) {
    // target是一个对象,这里的this就是调用_call方法的函数(母函数)
    // 我们需要实现的是将母函数的this指向到target,那么就可以:
    // 将母函数绑定到target的fn属性上,这样调用target.fn时它的this就指向了target
    target.fn = this;
    // 获取函数运行结果
    const result = target.fn(...arg);
    // 再将target上的fn属性删除
    delete target.fn;
    return result;
}

3、手写Function.bind

要求实现Function.bind函数的功能且该新函数命名为"_bind"。

 写代码前,我们先了解Function.bind是干什么的

Function.bind()函数与Function.call()函数类似,区别就是Function.bind()返回的是一个修改过this指向的新函数,而不是函数执行后的bind()方法创建一个新的函数,在 bind() 被调用时,该新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的初始参数,供调用时使用

语法:fn.bind(thisArg,arg1,arg2,...)

解释:

  thisArg:表示调用绑定函数时作为 this 参数传递给目标函数的值。如果使用new运算符构造绑定函数,则忽略该值。当使用 bind 在 setTimeout 中创建一个函数(作为回调提供)时,作为 thisArg 传递的任何原始值都将转换为 object。如果 bind 函数的参数列表为空,或者thisArg是null或undefined,执行作用域的 this 将被视为新函数的 thisArg。
  arg1,arg2,...:表示指定的参数列表。

bind() 方法返回一个原函数的拷贝,并拥有指定的 this 值和初始参数。

核心步骤有:

  1. 创建一个新this用来保存旧的this对象
  2. 返回一个匿名函数,该匿名函数返回通过apply修改了指针指向的函数运算结果

完整代码:

Function.prototype._bind = function(target, ...arguments1) {
    const _this = this
    return function(...arguments2) {
        return _this.apply(target,arguments1.concat(arguments2))
    }
}

4、new操作符

要求实现new操作符的功能。

实现一个仿new功能的新"_new"函数,该函数会返回一个对象,该对象的构造函数为函数参数、原型对象为函数参数的原型,核心步骤有:

  1. 创建一个新对象
  2. 获取函数参数
  3. 将新对象的原型对象和函数参数的原型连接起来
  4. 将新对象和参数传给构造器执行
  5. 如果构造器返回的不是对象,那么就返回第一个新对象

完整代码:

const _new = function() {
    const obj1 = {};

    // 获取函数参数
    const Fn = arguments[0]; 

    // 为obj1 新创建的对象添加属性 `__proto__`,将该属性链接至构造函数的原型对象(设置它的原型为构造函数的原型对象)
    Object.setPrototypeOf(obj1, Fn.prototype);

    // 将ovj1的对象作为 `this` 的上下文
    const object2 = Fn.apply(obj1, [].slice.call(arguments, 1));
    
    // 如果该函数没有返回对象,则返回 `this`
    return object2 instanceof Object ? object2 : object1
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值