`

get set 特性

 
阅读更多

get/set访问器不是对象的属性,而是属性的特性。请看《对象属性的特性一文》

 

这里着重介绍[[Get]]/[[Set]]就是我们所说的get/set访问器

先说一个书上说的 get/set访问器行为特点:get/set访问器可以不用定义,不定义也可以读写属性值。也可以只定义一个。只定义get,则被描述的属性只可读,不可写。只定义set,则被描述的属性只可写,不可读。

 

要改变属性的get /set 特性,有两种方式:

a.就是用Object.defineProperty()

1
2
3
4
5
6
7
8
9
10
11
var object={
_name:"Daisy"
};
Object.defineProperty(object,"name",{//这里的方法名name,就表示定义了一个name属性(因此才能通过object.name访问),只定义了getter访问器,没有定义[[value]]值
get:function (){//只定义了get 特性,因此只能读不能写
return this._name;
}
});
alert(object.name);//"Daisy"
object.name="jack";//只定义了getter访问器,因此写入失效
alert(object.name);//"Daisy"

注意Object.defineProperty(object,pro,{})中的属性名一定要和object.pro访问的属性对应

b.就是用用 get set 关键字:

1
2
3
4
5
6
7
8
9
var object={
_name:"Daisy",
get name(){//这里的方法名name ,就表示定义了一个name属性(因此才能通过object.name访问),只定义了getter访问器,没有定义[[value]]值
return this._name;
}//get,set方法只是属性的特性 ,不是对象方法,决定属性能否、怎么读写
};
alert(object.name);// Daisy这里去掉下划线 方法就是Daisy ;加上就是undefined
object.name="jack";//只定义了getter访问器,因此只能读不能写
alert(object.name);//Daisy

以上两种方法等效。注意的是以上两种方法objec象当中都将有有两个属性:_name(有初始值) name(无初始值),通过浏览器控制台可以看到

那么这个name属性实在什么时候定义的呢?我们知道Object.defineProperty(object,pro,{})可以给对象定义一个新属性pro,既然get pro(){}/set pro(){}和Object.defineProperty(object,pro,{})等效,则也会定义一个新属性pro .这就是为什么object里面有两个属性的原因。

(3)在此篇文章中网络之美 JavaScript中Get和Set访问器的实现代码关于标准标准的Get和Set访问器的实现:引发的思考

我自己也写了一个一样的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function Foo(val){
this.value=val;//定义了value属性 并没有定义_value
}
Foo.prototype={
set value(val){//注意方法名和属性名相同,在prototype里定义了value属性
this._value=val;
},
get value(){//方法名和属性名相同,在prototype里面定义了value属性和它的get 特性
return this._value;
}
}; //访问器返回和设置的都是_name,这里并没有定义_name属性为什么也可以读可以写????     
var obj=new Foo("hello");     
alert(obj.value);//"hello"     
obj.value="yehoo";     
alert(obj.value);//"yehoo"

为了解决以上这个疑问,做了很多测试,我们一一来看:

先看这个例子,在prototype里面只定义get 特性,在obj.value读value属性时,在实例里面寻找没有,然后在原型里面找到,调用的是原型的get方法,只能读不能写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function Foo(val){
this._value=val;//这里 的属性是带下划线的,初始化实例对象的_value属性,_value属性可读可写
}
Foo.prototype={
// set value(val){//注意方法名和属性名相同,在prototype里定义了value属性
// this._value=val;
// },
get value(){//方法名和属性名相同,在prototype里面定义了value属性和它的get 特性
return this._value;
}
};
var obj=new Foo("hello");
alert(obj.value);//hello 访问的是prototype里面的value 属性
obj.value="yehoo";//只定义了name 属性的get 特性,因此只能读不能写,写入失效
alert(obj.value);//hello

如果构造函数里面this._value 去掉下划线,在prototype里面定义的value属性,定义了get 特性。依然可以控制value属性的读写 。也就是说obj.value访问属性时,会调用get方法,先在对象本身寻找,如果没有,再到prototype寻找,如果都没有才算没有定义,默认的既可读又可写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function Foo(val){
this.value=val;//在原型里面只定义了value的get特性,因此这里写入失效
}
Foo.prototype={
// set value(val){//注意方法名和属性名相同,在prototype里定义了value属性的set特性
// this._value=val;
//},
//value:"hah",//即使手动写入value值,由于get方法返回的是this._value,因此也不能正确读取value:"hah"
//只要声明了get pro (){}和set pro (){}属性就都能读能写,但是如果函数定义错误,依然不能按要求访问到正确的属性值
get value(){//方法名和属性名相同,在prototype里面定义了value属性和它的get 特性
return this._value;
}
};
var obj=new Foo("hello");//"hello"没有写入成功
alert(obj.value);//undefined
obj.value="yehoo";//只定义了get 特性,因此只能读不能写,写入失效
alert(obj.value);//undefined

为了证明上面例子是可读不可写的:手动写入_value:"hah",就可以读取value 但不能写入。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function Foo(val){
this.value=val;//在原型里面只定义了value的get特性,因此这里写入失效
}
Foo.prototype={
// set value(val){//注意方法名和属性名相同,在prototype里定义了value属性的set特性
// this._value=val;
//},
_value:"hah",//即使手动写入value值,由于get方法返回的是this._value,因此也不能正确读取value:"hah"
//只要声明了get pro (){}和set pro (){}属性就都能读能写,但是如果函数定义错误,依然不能按要求访问到正确的属性值
get value(){//方法名和属性名相同,在prototype里面定义了value属性和它的get 特性
return this._value;
}
};
var obj=new Foo("hello");//"hello"没有写入成功
alert(obj.value);//"hah"
obj.value="yehoo";//只定义了get 特性,因此只能读不能写,写入失效
alert(obj.value);//"hah"

如果手动写入的是value:"hah",那么可以争取读取value的值吗?由于get方法返回的this._value并没有定义,obj.value读取value值调用get value(){}方法失效,但是value仍然不能写入。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function Foo(val){
this.value=val;//在原型里面只定义了value的get特性,因此这里写入失效
}
Foo.prototype={
// set value(val){//注意方法名和属性名相同,在prototype里定义了value属性的set特性
// this._value=val;
//},
value:"hah",//即使手动写入value值,由于get方法返回的是this._value,因此也不能正确读取value:"hah"
//只要声明了get pro (){}和set pro (){}属性就都能读能写,但是如果函数定义错误,依然不能按要求访问到正确的属性值
get value(){//方法名和属性名相同,在prototype里面定义了value属性和它的get 特性
return this._value;
}
};
var obj=new Foo("hello");//"hello"没有写入成功
alert(obj.value);//undefined 读取失效 因为只要obj.value就会调用get ,而get返回的是this._value,没有这个值,因此undefined
obj.value="yehoo";//只定义了get 特性,因此只能读不能写,写入失效
alert(obj.value);//undefined

再看这个例子,get set 都定义了,但是返回没有定义的this._value。可以发现value既可读又可写。去掉原型里面的get set方法,依然可读可写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function Foo(val){
this.value=val;
}
Foo.prototype={
set value(val){
this._value=val;
},
get value(){
return this._value;
}
};
var obj=new Foo("hello");
alert(obj.value);//hello
obj.value="yehoo";
alert(obj.value);//yehoo
function Foo(val){
this.value=val;
}
//和平时的操作是一样的了,就是回到了不定义get /set访问器特性的默认状态
var obj=new Foo("hello");
alert(obj.value);//hello
obj.value="yehoo";
alert(obj.value);//yehoo

总结

只声明了get pro(){}属性 可读不可写;

只声明 set pro(){}属性可写不可读。

如果都不声明,属性可读可写;

如果都声明就按照,get set 定义的方法,读写;

如果都声明了,但是定义的读写方法不能正确读写,get/set失效。变成默认的可读可写

在prototype里面定义的value属性,定义了get 特性。依然可以控制value属性的读写 。也就是说obj.value访问属性时,会调用get方法,先在对象本身寻找,如果没有,再到prototype寻找,如果都没有才算没有定义,默认的既可读又可写。

补充:

1
2
3
4
5
6
7
8
不管是用get pro(){}/set pro (){}
 
还是用Object.defineProperty(object,pro,{
 
 
         get:function (){
           return this._name;
           } });

pro不能和 return this. 后面的属性一样,不然会报错,在get value(){}方法里返回 this.value,就会又去调用value的get 方法,因此陷入死循环,造成方法栈溢出。

分享到:
评论

相关推荐

    C# get与set操作.rar

    在C#编程语言中,`get`和`set`是访问器方法,它们用于属性(Property)的定义,提供了一种安全的方式来读取和修改对象的私有成员。属性是类的一个特性,它允许我们像访问字段一样访问数据,但同时提供了额外的控制和...

    flex例程一,关于如何建GET,SET

    在Flex中,GET和SET方法是面向对象编程中的基本概念,用于访问和修改对象的属性。以下将详细介绍Flex中GET和SET方法的使用以及它们的重要性。 GET方法在Flex中是用来获取一个对象属性值的函数。它允许你安全地读取...

    经典讲解C# get set

    ### C#中的Get和Set详解:提升代码安全性与封装性 在C#编程语言中,`get` 和 `set` 是实现属性访问器的核心组成部分,它们不仅增强了代码的安全性,还提高了程序的封装性,是面向对象编程(OOP)的重要实践之一。本文...

    eclipse get set方法自动注释

    本文将详细介绍如何在Eclipse中利用内置特性来自动添加基于属性文档注释的getter和setter方法。 一、Eclipse生成getter和setter方法的基本步骤 1. 首先,确保你已经在Eclipse中创建了一个Java类,并定义了至少一个...

    vue计算属性get和set用法示例

    在Vue实例中定义计算属性时,我们通常使用对象形式,其中包含`get`和`set`函数: ```javascript computed: { b: { // getter函数定义了当读取b时的返回值 get: function() { return this.a + 10; }, // 如果...

    经典讲解C# get set.docx

    C#中的get和set是访问器,用于控制类的私有成员(如字段)的访问。它们是构建属性的关键部分,属性是C#中一种特殊的方法,提供了对类内部数据的封装和保护。属性并不直接表示内存位置,而是提供了一种访问和修改对象...

    vue.js的computed,filter,get,set的用法及区别详解

    在Vue.js开发过程中,computed(计算属性)、filter(过滤器)、get、set是经常会用到的一些概念和工具,它们各自在不同的场景下发挥着重要的作用。本文将会详细介绍它们的用法以及区别。 **Computed(计算属性)**...

    java中set和get方法的理解

    ### Java中Set和Get方法的理解 #### 一、引言 在Java编程中,`set`和`get`方法是非常常见的编程模式,特别是在面向对象编程(OOP)中。这两个方法通常用于封装类的属性,从而提供了对这些属性的访问和修改的方式。...

    eclipse get/set方法自动加上字段注释

    在"eclipse get/set方法自动加上字段注释"的场景中,当你在Eclipse中创建一个新属性或者选择已有属性时,可以通过右键点击属性选择"Source" -> "Generate Getters and Setters"来生成相应的get和set方法。...

    get set方法生成注释和字段注释.rar

    在Java编程语言中,"get"和"set"方法是面向对象设计中常见的特性,用于访问和修改对象的私有属性。这些方法通常被称为getter和setter,是封装原则的重要体现,能够保护数据的安全性,避免直接暴露对象的内部状态。在...

    Eclipse右键生成get、set方法.rar

    Eclipse是一款强大的集成开发环境(IDE),它为开发者提供了丰富的功能,包括便捷地自动生成get、set方法。下面将详细解释如何在Eclipse中使用这一特性,以及它背后的原理和最佳实践。 一、Eclipse生成get、set方法...

    SNMP实例大全--snmp4j(get ,trap,set,取mib)

    本文将详细介绍SNMP实例,特别是通过Java库snmp4j实现的GET、GETNEXT、SET操作以及TRAP发送和MIB获取。 1. **SNMP基本概念** SNMP由三个主要组件构成:管理站(Manager)、代理(Agent)和管理信息库(MIB)。管理...

    JAVA动态对象装配实现 测试--初步实现bean的set/get功能

    在Java中,Bean通常是指符合JavaBeans规范的Java类,它们是可重用的组件,具有无参数的构造函数、`get`和`set`方法(用于访问属性)以及可以序列化的特性。JavaBeans允许开发者在运行时通过反射机制来创建、配置和...

    .net get set用法小结第1/3页

    ### .NET中的Get和Set用法详解 #### 一、引言 在.NET框架下的C#编程语言中,属性(Property)是一个非常重要的概念。它不仅增强了类的设计灵活性,还提高了代码的安全性和可维护性。本文将深入探讨.NET中属性...

    asp.net get set用法第1/2页

    属性头定义了属性的类型和名称,而存储器则包括了get和set访问器。get访问器用于读取属性值,而set访问器用于设置属性值。声明属性的一般形式可以写成如下: ```csharp 修饰符 类型 属性名 { get { /* get存取程序...

    Myeclipse10.7 封装类 自动设置 Get Set方法中文注释设置

    3. **生成Get、Set方法**:光标放在属性定义行上,使用快捷键`Alt + Shift + S`(或右键选择"Source" -> "Generate Getters and Setters"),在弹出的对话框中,勾选你想要生成的get和set方法,然后点击"OK"。...

    ES6 javascript中class类的get与set用法实例分析

    在ES6中的类中,可以使用get和set关键字来定义属性的存取器(accessor),类似于在ES5中的对象字面量内使用getter和setter方法。这允许开发者自定义属性值被获取或设置时的行为。 ### get和set关键字的使用 在ES6...

    可以在 VS2008 里自动设置 set get 属性的一个 宏

    为了解决这个问题,VS2008提供了一个方便的宏功能,可以自动生成set和get属性,大大提高了编码效率。 首先,我们需要理解什么是宏。在编程术语中,宏是一种预处理器指令,它允许开发者定义一个简短的名称(宏名),...

    vue数据双向绑定原理解析(get & set)

    Vue.js 是一款流行的前端JavaScript框架,以其高效的数据绑定和组件化特性著称。在MVVM(Model-View-ViewModel)架构中,Vue 实现了一种称为“数据双向绑定”的机制,使得视图(View)与模型(Model)之间可以保持...

Global site tag (gtag.js) - Google Analytics