gpt4 book ai didi

node.js - obj.__proto__ = events.EventEmitter.prototype 和 obj.prototype.__proto__ = events.EventEmitter.prototype 有什么区别

转载 作者:搜寻专家 更新时间:2023-10-31 23:35:50 27 4
gpt4 key购买 nike

obj.prototype.__proto__ = events.EventEmitter.prototype

我有时会看到上面的代码,我用谷歌搜索了一下,他们说这一行将所有 EventEmitter 属性复制到 obj。而且我还看到了这样的代码:

obj.__proto__ = events.EventEmitter.prototype

所以我想知道它们是否相同?


我在这个 article 中看到了第一个用法,其中作者给出了例子:

var events = require('events');
function Door(colour) {
this.colour = colour;
events.EventEmitter.call(this);
this.open = function()
{
this.emit('open');
}
}
Door.prototype.__proto__ = events.EventEmitter.prototype;
var frontDoor = new Door('brown');
frontDoor.on('open', function() {
console.log('ring ring ring');
});

frontDoor.open();

他解释道:

This line: Door.prototype.__proto__ = events.EventEmitter.prototype; Copies all of the EventEmitter properties to the Door object.

关于第二种方式,我在hexo的源码里看到了,在init.js中,有代码:

    var hexo = global.hexo = {
get base_dir(){return baseDir},
get public_dir(){return baseDir + 'public/'},
get source_dir(){return baseDir + 'source/'},
get theme_dir(){return baseDir + 'themes/' + config.theme + '/'},
get plugin_dir(){return baseDir + 'node_modules/'},
get script_dir(){return baseDir + 'scripts/'},
get scaffold_dir(){return baseDir + 'scaffolds/'},
get core_dir(){return path.dirname(dirname) + '/'},
get lib_dir(){return dirname + '/'},
get version(){return version},
get env(){return env},
get safe(){return safe},
get debug(){return debug},
get config(){return config},
get extend(){return extend},
get render(){return render},
get util(){return util},
get call(){return call},
get i18n(){return i18n.i18n},
get route(){return route},
get db(){return db}
};

hexo.cache = {};

// Inherits EventEmitter
hexo.__proto__ = EventEmitter.prototype;

// Emit "exit" event when process about to exit
process.on('exit', function(){
hexo.emit('exit');
});

最佳答案

说法不一样。

我希望看到类似 Constructor.prototype.__proto__ = events.EventEmitter.prototype 的内容,而不是 obj.prototype.__proto__ = events.EventEmitter.prototype , (其中 Constructor 是任何类型的构造函数,因此可以有任何名称。它们通常大写。)因为 prototype 属性通常仅在函数上可用,并且定义为常规(非函数)对象的属性时没有任何特殊含义。

换句话说,第一行代码中的 obj 应该是一个(构造函数)函数才有意义,并且很少看到一个函数具有像 这样的通用变量名对象.

如果您分享找到第一个语句的来源,这可能会澄清一切。


第二个例子是最简单的。没有涉及构造函数。 hexo 是一个用对象字面量创建的普通对象。作者希望通过 hexo 方法可以使用 EventEmitter 方法,因此他将 EventEmitter.prototype 分配给 __proto__ 属性,这实际上改变了hexo的原型(prototype)。

第一个代码示例稍微复杂一些。在这里,作者想要确保由 Door 函数构造的任何对象都将提供对 EventEmitter 方法的访问。任何由 Door 函数构造的对象都将以 Door.prototype 作为其原型(prototype)。这个特定的原型(prototype)现在以 EventEmitter 作为其原型(prototype),因此可以通过原型(prototype)链向上两步访问 EventEmitter 函数。

“将所有 EventEmitter 属性复制到 Door 对象。” - 这个特定的评论具有误导性。没有属性被复制。唯一发生的就是这个。

door = new Door
door.on("open", function() { console.log("door has opened")})

door 的原型(prototype)现在是Door.prototype。如果在尝试访问某个属性(在本例中为 on)时未找到它,则 JS 引擎将查看此原型(prototype)。 door 的原型(prototype) - Door.prototype - 也没有定义 on,因此 JS 引擎将查看 Door.prototype 有一个原型(prototype)。它确实以 events.EventEmitter.prototype 的形式出现。并且此对象确实定义了一个 on 属性。

希望这能让事情更清楚一些。 Javascript 原型(prototype)继承非常棘手。

另见 Confusion about setting something.prototype.__proto__

关于node.js - obj.__proto__ = events.EventEmitter.prototype 和 obj.prototype.__proto__ = events.EventEmitter.prototype 有什么区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18103767/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com