所以我想知道方法和获取方法之间的区别是什么?
有时候,最好允许访问返回一个 动态计算的值,或者您可能要反映状态 内部变量,而无需使用显式方法 通话
但是他们不达成相同的目标吗?为什么一个比另一个更好?
为什么这么说:
var obj = {
log: ['a', 'b', 'c'],
get latest() {
if (this.log.length == 0) {
return undefined;
}
return this.log[this.log.length - 1];
}
}
console.log(obj.latest);
有时最好只使用last()方法并调用obj.latest()。如果两种情况下都运行代码,那有什么意义呢?它们都不都是动态的吗?
文档also reads:
字母给您一种定义对象属性的方法,但是它们确实 在访问该属性之前,不计算该属性的值。
“访问”和“被叫”之间到底有什么区别?一个方法直到被调用才运行,就像一个属性直到包含它才被访问一样?那么意义在哪里呢?
答案 0 :(得分:1)
请注意,以下是意见。
getter用于检索特定属性的值,它允许您的对象具有基于其他属性值的动态属性,但其他方面的行为与预期的行为相同。即使使用普通的对象属性访问器myObject.dynamicProp
和myObject['dynamicProp']
访问该方法,该getter仍允许您定义访问该属性时所调用的方法。
正是出于这个目的而提供了信函。如果这是您要编写的方法的意图,请使用getter语法。
存在一些方法来做其他口头的,面向行动的事情,而不仅仅是返回您正在编写的对象的某些属性。
您总是可以编写一个获取方法,但是为什么呢?
因此,这取决于您的意图。吸气剂指定意图,如果您的意图是提供行为类似于对象属性的动态属性,则在方法上使用吸气剂。
希望有帮助!
已更新:
虽然这里有一些技术上的细微差别需要理解,尽管我倾向于使用上述吸气剂,但经过进一步思考,我还是说,您希望采取的方法取决于您:>
(1)是否要使用普通访问器访问此属性?您可以隐藏一些逻辑的动态属性吗? (它们本质上并没有真正地“隐藏”逻辑,但是看起来就像调用者的常规道具一样)。然后使用get()
。
(2)是否要使您的属性是动态的,使其更明显且更易读?除了基于对象的现有属性的当前值计算动态属性之外,您是否还在做其他事情?您可以显式调用该方法吗?然后使用一种方法,例如getLatest()
。
答案 1 :(得分:1)
根据MSDN上Object.defineProperty()
的文档
对象中存在的属性描述符有两种主要形式:数据 描述符和访问器描述符。数据描述符是一个属性 具有一个值的值,该值可能是可写的,也可能是不可写的。存取器 描述符是由一对getter-setter方法描述的属性 功能。描述符必须是这两种形式之一。它不可能是 两者。
数据和访问描述符都是对象。他们分享 以下可选键:
可配置,当且仅当可以更改此属性描述符的类型并且可以从相应对象中删除该属性时,才为true。默认为false。
可枚举,当且仅当在枚举相应对象的属性期间显示此属性时,才为true。默认为false。
数据描述符还具有以下可选键:
值与属性关联的值。可以是任何有效的JavaScript值(数字,对象,函数等)。默认为未定义。
可写,当且仅当与该属性关联的值可以使用赋值运算符更改时,才为true。默认为false。
访问者描述符还具有以下可选键:
获取用作属性的获取器的函数,如果没有获取器,则未定义。当访问该属性时,该函数将不带参数地调用,并且将其设置为访问该属性所通过的对象(由于继承,它可能不是在其上定义该属性的对象)。返回值将用作属性的值。默认为未定义。
设置用作属性设置器的函数,如果没有设置器,则未定义。分配属性后,将使用一个参数(将值分配给属性)调用此函数,并将其设置为通过其分配属性的对象。默认为未定义。
如果描述符都不是可写的值,则获取并设置 键,将其视为数据描述符。如果描述符同时具有 值或可写以及获取或设置键,则会引发异常。
这表明get
和set
分别拦截了访问呼叫和分配呼叫。
一个很好的示例(和描述)here指出了一个有用的清晰示例。
以一个人的名字和姓氏为例,通常需要全名。
person.setLastName('Smith');
person.setFirstName('Jimmy');
person.getFullName(); // Jimmy Smith
使用get
和set
键,可以像下面这样声明对象:
var person = {
firstName: 'Jimmy',
lastName: 'Smith',
get fullName() {
return this.firstName + ' ' + this.lastName;
},
set fullName (name) {
var words = name.toString().split(' ');
this.firstName = words[0] || '';
this.lastName = words[1] || '';
}
}
分配它,然后像这样访问它:
person.fullName = 'Jack Franklin';
console.log(person.firstName); // Jack
console.log(person.lastName) // Franklin
console.log(person.fullName) // Jack Franklin
这使开发人员可以与全名进行交互,而不会意外使名或姓未分配或分配不当。
最后,
use strict
指令将相应地对通过get
或set
定义的属性进行读写尝试。参见W3Schools。
"use strict";
var obj = {get x() {return 0} };
obj.x = 3.14; // This will cause an error