在javascript中获取和设置背后的想法是什么?

问题描述 投票:1回答:2

嘿伙计们,我目前正在学习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;?意思是为什么我只能通过我的代码示例直接更改它?我无法掌握概念和需要吗?有人可以向我解释一下吗?有人可能会给我一个易于理解的解释例子吗?

javascript object get set
2个回答
1
投票

对象具有属性和方法。属性是一种描述对象所处状态的方法,方法是改变该状态并让对象“行为”的方法:

 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引入了getset。在内部,它的行为与方法类似,在外部它看起来仍然像一个简单的属性:

 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:getset基本上是属性和方法的混合,结合两者的优点并允许一致性。


0
投票

getset属性称为"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!
© www.soinside.com 2019 - 2024. All rights reserved.