是否可以将实例方法添加到所有的“类”中?在JavaScript
Is it possible to add instance methods to all "classes" in JavaScript?
这更像是一个探索性的问题,看看JavaScript的核心内容是如何工作的。我意识到惯例是不重写任何核心JavaScript类,但我似乎就是无法理解这个。
你可以在JavaScript中创建类似于"类方法"的东西,通过像这样添加核心Function
原型:
Function.prototype.class_method = function() {
console.log("class method called")
}
var User;
User = (function() {
function User() {}
return User;
})();
User.class_method(); // "class method called"
我的问题是,是否有一种方法以类似的方式添加"实例方法"?像这样疯狂的东西,但下面的内容不起作用(或没有任何意义):
alias = Function.prototype.constructor;
Function.prototype.constructor = function() {
child = this;
child.prototype.instance_method = function() {
console.log("instance method called");
}
alias.apply(child);
}
var user = new User();
user.instance_method(); // method doesn't exist
这几乎就像你需要覆盖Function
类的constructor
方法,并从那里访问prototype
。这可能吗?
如果你像这样添加Object.prototype
,它会起作用:
Object.prototype.instance_method = function() {
console.log("instance method");
}
var user = new User();
user.instance_method(); // "instance method called"
但这似乎也不对,主要是因为看到console.log({});
更改在node.js控制台的输出令人困惑:
console.log({});
// {};
Object.prototype.instance_method = function() {
console.log("instance method");
}
console.log({});
// {"instance_method": [Function]}
如果你正在使用node.js,你应该能够使用Object.defineProperty
[MDN]并使新属性不可枚举:
Object.defineProperty(Object.prototype, 'instance_Method', {
value: function() {
console.log("instance method");
},
enumerable: false // it's already the default
});
这是在ECMAScript5中引入的,所以只有较新的浏览器才会支持。
了解原型何时起作用是很重要的。它只是一个对象,是一个函数的属性。它只有在使用new
关键字时才有意义。例子:
var Widget = function(val) {
this.value = val;
};
Widget.prototype.getValue = function() {
return this.value;
};
var widget1 = new Widget('test');
widget1.getValue(); // test
var widget2 = new Widget('test2');
widget2.getValue(); // test2
当使用new
时,js解释器将在实例上创建一个隐藏的_proto_
属性。这个原型链接只是构造函数的原型对象的引用,例如,调用构造函数时的Widget。
当您重写Function
构造函数时,您实际上是在修改Function.prototype
后创建的每个函数的_proto_
属性上添加了一些东西。
如果你在你的基类构造函数中声明child.prototype... = ...
,那么这个原型将没有意义,直到有东西"实例化"子,例如var child = new child();
。
A great Resource.
要回答你关于"实例方法"的问题,你只需要做下面的事情:
var Widget = function() {
this.method = function() {
return 'instance method';
};
};
Widget.prototype.method = function() {
return 'class method';
};
var widget1 = new Widget();
widget1.method(); // instance method
delete widget1.method;
widget1.method(); // class method
这是由于javascript的原型继承的实现。我之前提到的原型链接是这里的关键。当widget1
首次在构造函数Widget中创建时,method
被专门附加到widget1。此method
将不可用于其他实例。但是,原型上的method
在Widget的所有实例之间是共享的。
在运行时,当js解释器看到widget1.method();
时,它首先看到widget1
是否直接将method
作为其属性(js中的对象本质上只是哈希映射,其中的键被称为"属性")。在本例中,它将实例方法作为属性查找。但是,一旦删除实例方法,它将尝试遵循_proto_
链接,该链接只是对Widget的对象引用。原型(在调用构造函数时)。定义了Widget.prototype.method;因此,解释器将执行该语句。如果在继续遵循_proto_
链接时没有找到method
函数,则会出现运行时错误
- 如何理解“当类实例化时,JavaScript静态方法也是不可调用的”
- Javascript:在对象实例方法上使用apply()方法失败
- 用javascript在实例方法中实例化对象
- 如何在 Javascript 中同时拥有静态方法和实例方法
- 在 JavaScript 中修饰实例方法时出现问题
- 在Javascript中使用寄生继承,是否可以实现内省实例方法
- 调用类实例方法onclick javascript
- 在Javascript中调用不带传递函数的组合私有类成员的公共实例方法
- 如何在我的javascript文件中调用各种goog.i18n.TimeZone实例方法
- Javascript OOP -对象如何调用其实例方法
- 实例.方法不是函数(javascript)
- Javascript继承静态和实例方法/属性
- 何时使用对象.prototype / JavaScript实例方法
- 是否可以将实例方法添加到所有的“类”中?在JavaScript
- 访问实例方法时出现的JavaScript OO问题
- javascript实例方法未找到:object#
- JavaScript函数套用在实例方法上不起作用
- 如何从方法内部获得JavaScript类/实例方法的名称?
- JavaScript中的类/实例方法重写
- Javascript静态方法与原型/实例化方法在性能上的对比