JavaScript各种方法封装(2)

330 阅读1分钟
1. 实现new关键字

new 运算符用来创建用户自定义的对象类型的实例或者具有构造函数的内置对象的实例。实现要点:详细描述

  • new 会产生一个新对象;
  • 新对象需要能够访问到构造函数的属性,所以需要重新指定它的原型;
  • 构造函数可能会显示返回;
function objectFactory() {
    var obj = new Object()
    Constructor = [].shift.call(arguments)
    obj.__proto__ = Constructor.prototyoe
    var ret = Constructor.apply(obj, arguments)
    
    // ret || obj 这里这么写考虑了构造函数显示返回 null 的情况
    return typeof ret === 'object' ? ret || obj : obj
}

function person(name, age) {
    this.name = name
    this.age = age
}
let p = objectFactory(person, '布兰', 12)
console.log(p)  // { name: '布兰', age: 12 }
2. 实现一个 instanceof关键字

instanceof 就是判断构造函数的 prototype 属性是否出现在实例的原型链上。详细描述

function instanceOf(left, right) {
    let proto = left.__proto__
    while (true) {
        if (proto === null) return false
        if (proto === right.prototype) {
            return true
        }
        proto = proto.__proto__
    }
}
3. 实现Object.create

Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__

Object.create = function(proto, propertyObject = undefined) {
    if (typeof proto !== 'object' && typeof proto !== 'function') {
        throw new TypeError('Object prototype may only be an Object or null.')
    if (propertyObject == null) {
        new TypeError('Cannot convert undefined or null to object')
    }
    function F() {}
    F.prototype = proto
    const obj = new F()
    if (propertyObject != undefined) {
        Object.defineProperties(obj, propertyObject)
    }
    if (proto === null) {
        // 创建一个没有原型对象的对象,Object.create(null)
        obj.__proto__ = null
    }
    return obj
}
4. 实现Object.assign
Object.assign = function(target, ...source) {
    if (target == null) {
        throw new TypeError('Cannot convert undefined or null to object')
    }
    let ret = Object(target) 
    source.forEach(function(obj) {
        if (obj != null) {
            for (let key in obj) {
                if (obj.hasOwnProperty(key)) {
                    ret[key] = obj[key]
                }
            }
        }
    })
    return ret
}