我在test.js中保存了以下内容。它成功地在浏览器中扩展了Array,但它似乎不适用于node和require。有人可以解释这里有什么问题吗?
(function() {
Array.prototype.max = function() {
return console.log("Array.prototype.max");
};
return Array.max = function() {
return console.log("Array.max");
};
}).call(this);
然后,从终端:
> My-MacBook-Pro: me$ node
> var test = require("./test")
> [1,2,3].max()
TypeError: Object 1,2,3 has no method 'max'
at [object Context]:1:9
at Interface.<anonymous> (repl.js:171:22)
at Interface.emit (events.js:64:17)
at Interface._onLine (readline.js:153:10)
at Interface._line (readline.js:408:8)
at Interface._ttyWrite (readline.js:585:14)
at ReadStream.<anonymous> (readline.js:73:12)
at ReadStream.emit (events.js:81:20)
at ReadStream._emitKey (tty_posix.js:307:10)
at ReadStream.onData (tty_posix.js:70:12)
> Array.max()
TypeError: Object function Array() { [native code] } has no method 'max'
at [object Context]:1:7
at Interface.<anonymous> (repl.js:171:22)
at Interface.emit (events.js:64:17)
at Interface._onLine (readline.js:153:10)
at Interface._line (readline.js:408:8)
at Interface._ttyWrite (readline.js:585:14)
at ReadStream.<anonymous> (readline.js:73:12)
at ReadStream.emit (events.js:81:20)
at ReadStream._emitKey (tty_posix.js:307:10)
at ReadStream.onData (tty_posix.js:70:12)
答案 0 :(得分:5)
您可以创建包含扩展程序的文件:
array.extensions.js
if(!Array.prototype.Last){
Array.prototype.Last = function(){
return this.slice(-1)[0];
}
}
if(!Array.prototype.First){
Array.prototype.First = function(){
return this[0];
}
}
然后将此文件包含在您的启动文件中。
app.js:
require('{path}/array.extensions');
var express = require('express');
/* rest of your code */
在启动时引用此文件一次就足以使用......
答案 1 :(得分:0)
REPL中的每个命令都通过vm.runInContext
使用共享上下文对象执行。通过复制global
对象中的所有内容,在REPL初始化时创建此对象。由于require'd模块只会在之后将Array.prototype
扩展为已复制到上下文对象,因此修改后的版本永远不会公开。
或者至少我可以从the source code推断出来。我对V8的内部工作原理一无所知:)正如你现在可能已经发现的那样,你的例子在REPL之外工作正常。