Javascript 在object或object.prototype上定义属性?
我最近看到了JavaScript代码,其中getter和setter方法在构造函数方法的原型对象上定义 例如:Javascript 在object或object.prototype上定义属性?,javascript,oop,Javascript,Oop,我最近看到了JavaScript代码,其中getter和setter方法在构造函数方法的原型对象上定义 例如: Person.prototype.getFirstName = function() { return this.firstName; } 这是正确的吗 我的意思是: “this”指向调用该方法的对象的描述符 当我打电话给 console.log(Person.getFirstName()); console.log(Person.getFirstName()); 。。。没有
Person.prototype.getFirstName = function() {
return this.firstName;
}
这是正确的吗
我的意思是:
“this”指向调用该方法的对象的描述符
当我打电话给
console.log(Person.getFirstName());
console.log(Person.getFirstName());
。。。没有事先做一个物体
此外:
何时将属性附加到构造函数方法以及何时附加到原型对象,是否有一般规则
从我的观点来看,如果你不一定要创建一个对象的话,那么这个原型是正确的。因为该方法不使用必须单独设置对象的对象值。原型通过使用
new
关键字实例化来继承
因此,代码
var Person = function(){}
Person.prototype.getFirstName = function() {
return this.firstName;
}
Person.prototype.firstName = "test";
console.log(Person.getFirstName()); // Throw Uncaught TypeError
正确的方法是:
var Person2 = new Person()
Person2.getFirstName() // "test"
要测试此对象,请执行以下操作:
因此,Person
的Prototype
被设置为这个Person2的对象(继承)
这与Java或C语言中的类类似
当我打电话给
console.log(Person.getFirstName());
console.log(Person.getFirstName());
。。。没有事先做一个物体
出现错误,Person
没有getFirstName
属性
何时将属性附加到构造函数方法以及何时附加到原型对象,是否有一般规则
是的:
如果希望通过构造函数函数创建的对象(例如,在var obj=new Person()
中的obj
上)可以使用该方法,请将该方法放在构造函数函数的原型
对象(共享)上,或通过将该方法分配给此
上的属性,将该方法分配给构造函数中的对象(不共享)
如果希望该方法在构造函数本身上可用,请按照某些内置JavaScript方法的方式(如Date.parse
或Object.create
),将其分配给构造函数上的属性:
Person.doSomething = function() {
// ...
};
这些方法并不特定于构造函数创建的对象(这些方法中的
是对构造函数函数本身的引用,除非您做了一些改变)
如果你来自一种基于类的语言,一个非常松散的类比是属性(包括方法)在构造函数中为prototype
对象或this
指定的是实例属性,为构造函数本身指定的是静态属性。这是一个非常松散的类比,但有时很有用
以下是旧ES5和早期语法的完整示例:
function Person(name) {
this.getName = function() {
return name;
};
}
Person.prototype.sayHello = function() {
console.log("Hello, my name is " + this.getName());
};
Person.copy = function(other) {
return new Person(other.getName());
};
// Usage example
var joe = new Person("Joe");
joe.sayHello();
console.log("joe's name is " + joe.getName());
var joeagain = Person.copy(joe);
joeagain.sayHello();
在上述情况下:
getName
可用于由new Person
创建的实例。它是为每个对象单独创建的,不与其他实例共享。它允许我们获取人名,在本例中是只读的
sayHello
在由new Person
创建的实例上可用,因为它们从原型继承,原型由new Person
从Person.prototype
属性分配给它们。它在实例之间共享
copy
在实例上不可用(joe.copy()
将是一个错误),它是Person
本身的属性。在本例中,我们使用它来复制实例,但它可以用于任何用途
我个人不喜欢在原型中添加getter
,如果您只想访问实例值。您已经可以通过实例访问这些值:
function Person(name) {
this.firstname = name;
}
Person.prototype.getFirstname = function() {
return this.firstname;
}
var p = new Person('o-o');
console.log(p.firstname); //o-o
console.log(p.getFirstname()); //o-o
您可以向原型添加一个getter
,以传递不同的上下文:
var firstname = Person.prototype.getFirstname.call({firstname: 'other'});
console.log(firstname); // other
如果是这样的话,在原型中添加一个getter
来增加一些计算是有意义的:
Person.prototype.getFirstname = function() {
return new Date().toISOString + ': ' + this.firstname;
};
如果该策略适合您的需要,您可以以不同的方式编排代码:
var common = {
getValue = function(propName) {
return new Date().toISOString() + ': ' + this[propName];
}
};
function Person(name) {
this.firstname = name;
}
$.extend(Person.prototype, common); //jQuery extend
var p = new Person('o-o');
console.log(p.firstname); //o-o
console.log(p.getValue('firstname')); //today: o-o
使用通用的扩展您的原型:在开发过程中添加日志信息,并在生产过程中删除那些多余的日志信息。太棒了。您帮了我很多。谢谢。)