嘿伙计们,我目前正在学习get和set如何在javascript中运行。特别是谈论对象atm。
let person = {
_name: 'Lu Xun',
_age: 137,
set age(ageIn) {
if (typeof ageIn === 'number') {
this._age = ageIn;
}
else {
console.log('Invalid input');
return 'Invalid input';
}
},
get age() {
console.log(`${this._name} is ${this._age} years old.`);
return this._age;
}
};
person.age = 'Thirty-nine';
person.age = 39;
console.log(person.age);
例如在这段代码中。为什么我需要一个集合或获取,为什么我不能像这样访问它:person.age = 59;
?意思是为什么我只能通过我的代码示例直接更改它?我无法掌握概念和需要吗?有人可以向我解释一下吗?有人可能会给我一个易于理解的解释例子吗?
对象具有属性和方法。属性是一种描述对象所处状态的方法,方法是改变该状态并让对象“行为”的方法:
class Person {
constructor(name){
this.name = name; //name is a property
}
//And here weve got a method:
sayHi(){
alert(`Hi, im ${this.name}!`);
}
}
然而,在大多数情况下,它非常明确地分离“状态”和“行为”(又名属性和方法)有时它不是。让我们想象这个人有一个标签符号方法:
showLabel(){
document.body.innerHTML = this.name;
}
现在我们更改人名例如:
const person = new Person("Jake");
person.showLabel();
person.name = "Jack";
然而,标签不会更新:/,所以当我们将杰克改名为杰克时,他的品牌仍然显示杰克。那很糟。为此,发明了吸气剂和制定者。这些方法的主要目的是获取和设置属性(惊讶;)),但它们也可以防止像上面那样的故障,它们有很多优点,这就是为什么they are used excessively in other languages。 Person的样本设置器将是:
setName(name){
//Set
this.name = name;
//Prevent glitches
this.showLabel();
}
因此,我们不再直接设置person.name
,而是调用setter person.setName("Jack")
。但是现在我们在属性和属性之间存在不一致,不应该设置,而是使用setter。为了解决这种不一致性,js引入了get
和set
。在内部,它的行为与方法类似,在外部它看起来仍然像一个简单的属性:
get name(){ return this._name }
set name(value){
this._name = value;
this.showLabel();
}
适用于:
const person = new Person("Jake");
person.showLabel();
person.name = "Jack"; //let the magic happen ;)
TLDR:get
和set
基本上是属性和方法的混合,结合两者的优点并允许一致性。
get
和set
属性称为"Accessor Properties" and they differ from "Data properties"(即obj.prop = value
),因为它们允许在get和set操作期间实现逻辑,这对于验证和操作非常有用。
如果你有一个带有Person
属性的age
对象,这会有意义吗?
Person.age = "green";
当然不是,但常规的“数据”属性会允许它。但是,使用set
“accessor”属性,我们可以禁止超出范围的非数字和数字数据。
var Person = {
_age:0,
// Accessor Property:
get age() {
return _age;
},
set age(value) {
// Can't be non-numeric or out of range
if (/^\d+$/.test(value) && value > 0 && value < 110) {
this._age = value;
}
}
};
但是,当涉及到继承属性时,它们在处理set
操作方面也有所不同。
这是一个例子:
var Product = {
// Data Properties:
sku: 12345,
name: "Super Widget",
mfg: "ACME Corp.",
retail: 9.95,
suggestedWholesale: 14.95,
implementationDate: new Date(2012, 06, 04).toLocaleDateString(),
// Accessor Property:
get markup() {
// Return the difference between wholesale and retail price
return (this.suggestedWholesale - this.retail).toFixed(2);
},
set markup(value) {
// Markup cannot be more than 100
if (value <= 100) {
this.suggestedWholesale = this.retail + value;
}
}
};
// Make a new object that inherits from Product
var newProduct = Object.create(Product);
// When you GET a property value, the entire prototype chain is
// checked until the property is found or else you'll get undefined.
console.log(newProduct.name);
console.log(newProduct.markup);
// When you SET a property value, the property is ALWAYS used
// on the CURRENT object as an "own". If the property being
// set matches an inherited property of the same name, the new
// "own" property hides the inherited one.
newProduct.name = "FOO";
console.log(newProduct.name); // Successful override of inherited property
console.log(Product.name); // Original object still has original property value
// EXCEPTION: accessor properties - With these the prototype chain is used:
newProduct.markup = 101; // Not allowed according to inherited set logic
console.log(newProduct.markup); // Value doesn't change because inherited accessor set is used!