2015-12-29 58 views
1

我最近看到了JavaScript代码,其中getter和setter方法在构造函数方法的原型对象上定义。定义对象或object.prototype的属性?

例如:

Person.prototype.getFirstName = function() { 
    return this.firstName; 
} 

这是正确的吗?

我的意思是: 'this'指向调用该方法的对象的描述符。

当我打电话,会发生什么......

console.log(Person.getFirstName()); 

...未做一个对象之前?

此外:

是否有何时的属性附加到构造函数法和时附加到原型的对象一般规则?

如果您不一定需要创建对象,那么从我的角度来看,它是附加在原型上的。因为该方法不使用必须单独设置对象的对象的值。

回答

3

当我打电话,会发生什么......

console.log(Person.getFirstName()); 

...没有事先制作的对象?

您收到错误消息Person没有getFirstName属性。

是否有附加属性到构造函数方法和何时附加到原型对象的一般规则?

是:

如果你想方法可用上通过构造函数创建的对象(例如,obj,var obj = new Person()),将该方法放在构造函数的prototype对象(共享)上,或者通过分配给this(不共享)的属性将该方法分配给构造函数中的对象。

如果你想方法可用在构造函数本身,这样一些内置的JavaScript方法(如Date.parseObject.create),其分配给属性的构造函数:

Person.doSomething = function() { 
    // ... 
}; 

这些方法不是特定于由构造函数创建的对象(其中的this是对构造函数本身的引用,除非您采取某些措施使其不同)。

如果你从一个基于类的语言来,一个很宽松的比喻是,性质(包括方法)分配给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创建,因为他们从他们的原型,这是从Person.prototype财产分配给他们的new Person继承它。它在实例之间共享。

  • copy在实例上不可用(joe.copy()将是错误),它是Person本身的属性。在这种情况下,我们用它来复制实例,但它可能适用于任何事情。

+0

太棒了。你帮了我很多。谢谢。 :) –

0

原型获得通过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" 

为了测试这个对象:

所以PersonPrototype设为this对象PERSON2(继承)的

这类似于Class如Java或C#语言。

0

就个人而言,我不喜欢在原型中添加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 

扩展您的原型还带有一个多功能common:开发过程中添加日志记录信息并丢弃那些生产多余的日志记录信息。