手写JavaScript中的new方法

new的使用

如下所示,可以使用new来创建一个自定义构造函数的实例对象,在对象中可以使用构造函数原型上的方法以及构造函数中的属性:

function Person(name,age){
    this.name = name
    this.age = age
    // 返回非对象类型不会对new造成影响
    // return this.name + this.age
}
Person.prototype.say = function(){
    console.log('我是'+this.name+',今年'+this.age+'岁')
}
var obj = new Person('xxx',20)
console.log(obj)
obj.say()

分析可以得出,使用new创建对象时主要经过了以下几步:
1、创建一个新的空对象,如obj
2、对象obj会继承构造函数Person的原型(obj.proto === Person.prototype),以便使用构造函数上的方法(obj.say())
3、将构造函数Person的this指向对象obj,即可以将构造函数上的属性添加到对象上
4、如果构造函数Person没有返回对象,则返回新创建的对象

因此可以按步骤手写出new方法:

// 手写new方法
function myNew(constructor){
    // 首先判断传入的第一个参数是否是函数
    if(Object.prototype.toString.call(constructor) !== '[object Function]')
        throw new Error('error in params')
    // 然后获取到传入的其他参数(除去第一个)
    let args = Array.from(arguments).slice(1)
    // 创建一个空对象,让其继承构造函数的原型
    let newObj = Object.create(constructor.prototype)
    // 这种写法等价于:
    // let newObj = {}
    // newObj.__proto__ = constructor.prototype

    // 执行构造函数,让this指向newObject,使其具有构造函数的属性
    let result = constructor.apply(newObj,args)

    // 判断result的类型,如果是object或者function则直接返回
    let resultType = Object.prototype.toString.call(result)
    let isObject = (resultType === '[object Object]')
    let isFunction = (resultType === '[object Function]')
    if(isObject || isFunction){
        return result
    }
    else{
        // 否则返回新创建的对象
        return newObj
    }
}
// 测试一下
let obj = myNew(Person,'xxx',20)
console.log(obj)
obj.say()

其中的关键点是:
1、使用Object.create()创建对象
2、使用apply方法改变this的指向
3、使用Object.prototype.toString,call()来判断结果的类型

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
发布订阅模式又称观察者模式,是一种常见的设计模式,它定义了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。下面是手写JavaScript发布订阅模式的一种实现方式: ```javascript function PubSub() { this.subscribers = {}; } PubSub.prototype.subscribe = function(event, callback) { if (!this.subscribers[event]) { this.subscribers[event] = []; } this.subscribers[event].push(callback); }; PubSub.prototype.unsubscribe = function(event, callback) { if (!this.subscribers[event]) { return; } var index = this.subscribers[event].indexOf(callback); if (index > -1) { this.subscribers[event].splice(index, 1); } }; PubSub.prototype.publish = function(event, data) { if (!this.subscribers[event]) { return; } this.subscribers[event].forEach(function(callback) { callback(data); }); }; ``` 使用方式如下: ```javascript var pubsub = new PubSub(); function callback1(data) { console.log('callback1:', data); } pubsub.subscribe('event1', callback1); function callback2(data) { console.log('callback2:', data); } pubsub.subscribe('event2', callback2); pubsub.publish('event1', { message: 'hello' }); pubsub.publish('event2', { message: 'world' }); pubsub.unsubscribe('event1', callback1); pubsub.publish('event1', { message: 'hello again' }); ``` 输出结果为: ``` callback1: {message: "hello"} callback2: {message: "world"} ``` 当调用 `publish` 方法时,订阅了该事件的所有回调函数都将被执行,并且可以传递一个数据对象作为参数。调用 `subscribe` 方法注册一个回调函数,当该事件被发布时,该回调函数将被执行。调用 `unsubscribe` 方法取消订阅。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值