如何在@meta property属性中给属性附初始值

JavaScript对象的property属性详解
字体:[ ] 类型:转载 时间:
这篇文章主要介绍了JavaScript对象的property属性,详细讲解了property的各种属性,需要的朋友可以参考下
JavaScript中对象的property有三个属性:1.writable。该property是否可写。2.enumerable。当使用for/in语句时,该property是否会被枚举。3.configurable。该property的属性是否可以修改,property是否可以删除。
在ECMAScript 3标准中,上面三个属性的值均为true且不可改:新建对象的property是可写的、可被枚举的、可删除的;而在ECMAScript 5标准中,可通过property的描述对象(property descriptor)来对这些属性进行配置和修改。
如果将property的值信息也作为property的属性来看的话,对象中的property拥有四个属性:value、writable、enumerable和configurable。
对于用getter和setter方法来定义的property,由于其没有writable属性(property是否可写取决于setter方法是否存在),因此这种property也有四个属性:get、set、enumerable和configurable — get和set属性的值为function。
获取对象property的属性
ECMAScript 5标准中,可以通过Object.getOwnPropertyDescriptor()来获取对象自身某个property的属性信息: 代码如下:var o = {x:1};var a = Object.create(o);a.y = 3;console.log(Object.getOwnPropertyDescriptor(a, "y"));//Object {configurable=true, enumerable=true, writable=true, value=3}console.log(Object.getOwnPropertyDescriptor(a, "x"));//undefined可以看到,如果property不存在或者property继承自原型对象,则返回undefined。
设置对象property的属性
ECMAScript 5标准中,可以通过Object.defineProperty()来设置对象自身某个property的属性: 代码如下:Object.defineProperty(a, "y", {&&& value:3,&&& writable:true,&&& enumerable:false,&&& configuration:true});console.log(a.propertyIsEnumerable("y"));//false如果设置的property是从原型对象中继承而来的,那么JavaScript将在对象自身中创建一个同名的property,这与赋值操作的相关行为一致: 代码如下:Object.defineProperty(a, "x", {&&& value:1,&&& writable:true,&&& enumerable:false,&&& configuration:true});console.log(a.propertyIsEnumerable("x"));//falseconsole.log(o.propertyIsEnumerable("x"));//true除了修改property的属性,还可以将property改为用getter或setter访问: 代码如下:Object.defineProperty(a, "y", {&&& get:function(){return 42;}});console.log(a.y);//42在使用Object.defineProperty()时,property描述对象中的属性值可以部分忽略,当属性值有所忽略时,JavaScript中的处理规则如下:
如果property是新建的,则所有忽略的属性值均为false或undefined。如果property已存在,则所有忽略的属性值维持原样不变。
批量设置对象property的属性
如果需要一次性设置多个property的属性,可以使用Object.defineProperties()语句。该语句将返回修改后的对象。 代码如下:Object.defineProperties(a, {&&& "y":{value:79, writable:true, enumerable:true, configurable:true},&&& "z":{value:99, writable:true, enumerable:true, configurable:true}});console.log(a);//Object {y=79, z=99}property属性设置规则
当对property属性进行修改时,必须遵循以下规则。如果违反规则,JavaScript将报TypeError错误:
如果对象不是extensible的,则只能修改已有property的属性,无法添加新的property。如果property的configurable属性为false,则无法修改configurable和enumerable属性的值,对于writable属性,可以将其从true改为false,但无法将其从false改为true。如果property由getter和setter定义,则getter和setter方法无法被修改。如果property的configurable属性和writable属性均为false,则property值不可改。如果property的writable属性为false,但其configurable属性为true,则property值依然可以修改。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具Properties读取配置文件中的属性值
import java.util.Pimport org.apache.log4j.Lpublic class PropertyReader {
private static Properties props=new Properties();
private final Logger logger = Logger.getLogger(getClass());
& &public PropertyReader(){
&loadConfigFile("fileupload.properties");
& &public PropertyReader(String fileName){
&loadConfigFile(fileName);
private &void loadConfigFile(String fileName) {
java.io.InputStream fis = getClass().getResourceAsStream("/" + fileName);
props.load(fis);
//props.load(new FileInputStream("/"+fileName));
catch(Exception e) {
logger.error("load file failed!",e);
public String getProperty(String key){
return props.getProperty(key);
public int size(){
return props.size();
public Properties getProperties(){
* @param args
*/ public static void main(String[] args) {
PropertyReader pr = new PropertyReader("config.properties");
String a = pr.getProperty(null+"");
System.out.println(a==null?"":a); }}
TA的最新馆藏iOS:OC在Category中使用@property定义属性 - 简书
iOS:OC在Category中使用@property定义属性
有时候写Category需要@property定义属性。这个时候就需要使用@dynamic来进行修饰。@dynamic是什么意思?@dynamic修饰就是表明这个属性需要程序员自己管理该属性的setter和getter方法这个时候就需要重写getter和setter方法了。
(简单粗暴)直接上代码
@interface UITableView (Extension) &TableViewDelegate&
@property (nonatomic, copy) NSString *
#import "UITableView+Extension.h"
// 定义一个指针
static const void *Name = &N
@implementation UITableView (Extension)
- (void)setName:(NSString *)name {
objc_setAssociatedObject(self, Name, name, OBJC_ASSOCIATION_COPY);
- (NSString *)name {
return objc_getAssociatedObject(self, Name);
有什么不明白的可以加我QQ交流:(加的时候请注明来自简书)
我要一步一步往上爬您的位置: >>
  在《》中,我通过界面控件ID与作为数据源的实体属性名之间的映射实现了批量数据绑定。由于里面频繁涉及对属性的反射&&通过反射从实体对象中获取某个属性值;通过反射为控件的某个属性赋值,所以这不是一种高效的操作方式。为了提升性能,我通过IL Emit的方式创建了一个PropertyAccessor组件,以实现高效的属性操作。如果你看了我在文中给出的三种属性操作性能的测试结果,相信会对PropertyAccessor的作用有深刻的印象。[源代码从下载]
一、PropertyAccessor与PropertyAccessor&T&的API定义
二、如何通过PropertyAccessor获取属性值和为属性赋值
三、Set和Get的实现
四、比较三种属性操作的性能
五、PropertyAccessor的ExpressionTree版本
  一、PropertyAccessor与PropertyAccessor&T&的API定义
  我们照例从编程&&即如何使用PropertyAccessor进行属性操作(获取属性值/为属性赋值)讲起,所有先来看看PropertyAccessor提供了哪些API功我们调用。从下面的代码片断我们可以看到,PropertyAccessor得构造函数接受两个参数:目标对象的类型和属性名称,然后通过Get获取目标对象相应属性的值,通过Set方法为目标对象的属性进行赋值。此外,PropertyAccessor还提供了两个对应的Get/Set静态方法通过指定具体的目标对象和属性名称实现相同的操作。
public class PropertyAccessor{
public PropertyAccessor(Type targetType, string propertyName);
public object Get(object obj);
public void Set(object obj, object value);
public static object Get(object obj, string propertyName);
public static void Set(object obj, string propertyName, object value);
//Others...}
  如果预先知道了目标对象的类型,可能使用泛型的PropertyAccessor&T&会使操作更加方便。PropertyAccessor&T&继承自PropertyAccessor,定义如下:
public class PropertyAccessor&T& : PropertyAccessor{
public PropertyAccessor(string propertyName);
public static object Get(T obj, string propertyName);
public static void Set(T obj, string propertyName, object value);}
  二、如何通过PropertyAccessor获取属性值和为属性赋值
  现在我们来演示如何通PropertyAccessor&T&来对目标对象的属性赋值,以及如何或者目标对象相应属性的值。现在我们定义如下一个实体类型:Contact。
public class Contact{
public string
FirstName { get; set; }
public string
LastName { get; set; }
public string
Gender { get; set; }
public int?
Age { get; set; }
public DateTime?
Birthday { get; set; }}
  然后我们在一个Console应用的Main方法中编写如下一段代码。在这段代码中,我创建了一个Contact对象,然后通过调用PropertyAccessor&Contact&类型的静态方法Set为该对象的各个属性进行复制。然后将各个属性值按照一定的格式打印出来,而获取属性值是通过调用静态方法Get完成的。
static void Main(string[] args){
var contact = new Contact();
PropertyAccessor&Contact&.Set(contact, "FirstName", "Jiang");
PropertyAccessor&Contact&.Set(contact, "LastName", "Jin Nan");
PropertyAccessor&Contact&.Set(contact, "Gender", "Male");
PropertyAccessor&Contact&.Set(contact, "Age", 30);
PropertyAccessor&Contact&.Set(contact, "Birthday", new DateTime(1981, 8, 24));
Console.WriteLine("Contact({0} {1})\n\tGender\t:{2}\n\tAge\t:{3}\n\tBirth\t:{4}",
PropertyAccessor&Contact&.Get(contact, "FirstName"),
PropertyAccessor&Contact&.Get(contact, "LastName"),
PropertyAccessor&Contact&.Get(contact, "Gender"),
PropertyAccessor&Contact&.Get(contact, "Age"),
PropertyAccessor&Contact&.Get(contact, "Birthday"));}
  输出结果:
Contact(Jiang Jin Nan)
:8/24/1981 12:00:00 AM
  三、Set和Get的实现
  虽然PropertyAccessor是一个很小的组件,但也不太可能将所有的代码列出来。在这里,我只是只能将核心部分作一下简单介绍,如果你想了解整个PropertyAccessor的实现,可以下载源代码。PropertyAccessor的两个核心的方法就是Get和Set。而在内部,它们对应着两个核心的方法:CreateGetFunction和CreateSetAction,它们利用IL Emit。下面是CreateGetFunction的实现:创建一个DynamicMethod对象,通过IL Emit调用属性的Getter方法,并将结果返回。最后通过DynamicMethod的CreateDelegate方法创建一个Func&object,object&委托对象并在本地缓存起来,供或许的获取属性值操作之用。
private Func&object, object& CreateGetFunction(){
DynamicMethod method = new DynamicMethod("GetValue", typeof(object), new Type[] { typeof(object) });
ILGenerator ilGenerator = method.GetILGenerator();
ilGenerator.DeclareLocal(typeof(object));
ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Castclass, this.TargetType);
ilGenerator.EmitCall(OpCodes.Call, this.GetMethod, null);
if (this.GetMethod.ReturnType.IsValueType)
ilGenerator.Emit(OpCodes.Box, this.GetMethod.ReturnType);
ilGenerator.Emit(OpCodes.Stloc_0);
ilGenerator.Emit(OpCodes.Ldloc_0);
ilGenerator.Emit(OpCodes.Ret);
method.DefineParameter(1, ParameterAttributes.In, "value");
return (Func&object, object&)method.CreateDelegate(typeof(Func&object, object&));}
  与CreateGetFunction类似,CreateSetAction同样创建一个DynamicMethod对象,通过IL Emit的方式调用属性的Setter方法。最后通过DynamicMethod的CreateDelegate方法创建一个Action&object,object&委托对象并在本地缓存起来,供后续的属性赋值操作之用。
private Action&object, object& CreateSetAction(){
DynamicMethod method = new DynamicMethod("SetValue", null, new Type[] { typeof(object), typeof(object) });
ILGenerator ilGenerator = method.GetILGenerator();
Type paramType = this.SetMethod.GetParameters()[0].ParameterT
ilGenerator.DeclareLocal(paramType);
ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Castclass, this.TargetType);
ilGenerator.Emit(OpCodes.Ldarg_1);
if (paramType.IsValueType)
ilGenerator.Emit(OpCodes.Unbox, paramType);
if (valueTpyeOpCodes.ContainsKey(paramType))
OpCode load = (OpCode)valueTpyeOpCodes[paramType];
ilGenerator.Emit(load);
ilGenerator.Emit(OpCodes.Ldobj, paramType);
ilGenerator.Emit(OpCodes.Castclass, paramType);
ilGenerator.EmitCall(OpCodes.Callvirt, this.SetMethod, null);
ilGenerator.Emit(OpCodes.Ret);
method.DefineParameter(1, ParameterAttributes.In, "obj");
method.DefineParameter(2, ParameterAttributes.In, "value");
return (Action&object, object&)method.CreateDelegate(typeof(Action&object, object&));}
  四、比较三种属性操作的性能
  我想大家最关心的还是&性能&的问题,现在我们就来编写一个性能测试的程序。在这个程序中我们比较三种典型的属性操作耗费的时间:直接通过属性赋值(或者取值)、通过IL Emit(即PropertyAccessor)和PropertyInfo对属性赋值(或者取值)。我们定义两个简单的类型Foo和Bar,Foo中定义一个类型和名称为Bar的可读写的属性。
public class Foo{
public Bar Bar { get; set; }}public class Bar{ }
  下面是用于比较三种属性复制操作的测试程序SetTest,方法参数为复制操作的次数,最后将三种属性赋值操作的总时间(单位毫秒)分别打印出来。
public static void SetTest(int times){
Foo foo = new Foo();
Bar bar = new Bar();
Stopwatch stopwatch = new Stopwatch();
PropertyAccessor&Foo& propertyAccessor = new PropertyAccessor&Foo&("Bar");
PropertyInfo propertyInfo = typeof(Foo).GetProperty("Bar");
stopwatch.Start();
for (int i = 0; i & i++)
long duration1 = stopwatch.ElapsedM
stopwatch.Restart();
for (int i = 0; i & i++)
propertyAccessor.Set(foo, bar);
long duration2 = stopwatch.ElapsedM
stopwatch.Restart();
for (int i = 0; i & i++)
propertyInfo.SetValue(foo, bar, null);
long duration3 = stopwatch.ElapsedM
Console.WriteLine("{0,-10}{1,-10}{2,-10}{3,-10}", times, duration1, duration2, duration3);}
  下面是下面是用于比较三种或者属性值操作的测试程序GetTest,定义形式和上面一样:
public static void GetTest(int times){
Foo foo = new Foo { Bar = new Bar() };
Stopwatch stopwatch = new Stopwatch();
PropertyAccessor&Foo& propertyAccessor = new PropertyAccessor&Foo&("Bar");
PropertyInfo propertyInfo = typeof(Foo).GetProperty("Bar");
stopwatch.Start();
for (int i = 0; i & i++)
var bar = foo.B
long duration1 = stopwatch.ElapsedM
stopwatch.Restart();
for (int i = 0; i & i++)
var bar = propertyAccessor.Get(foo);
long duration2 = stopwatch.ElapsedM
stopwatch.Restart();
for (int i = 0; i & i++)
var bar = propertyInfo.GetValue(foo, null);
long duration3 = stopwatch.ElapsedM
Console.WriteLine("{0,-10}{1,-10}{2,-10}{3,-10}", times, duration1, duration2, duration3);}
  然后,我们在Console应用的Main方法中编写如下的代码,旨在测试次数分别为100000(十万)、1000000(一百万)和(一千万)下三种不同形式的属性操作所耗用的时间。
static void Main(string[] args){
Console.WriteLine("{0,-10}{1,-10}{2,-10}{3,-10}", "Times", "General", "IL Emit", "Reflection");
SetTest(100000);
SetTest(1000000);
SetTest();
Console.WriteLine();
GetTest(100000);
GetTest(1000000);
GetTest();}
  输出结果:
Reflection100000
2041000000
18919 100000
1531000000
  由于我的笔记本已经差不多5年的历史,性能不是很好,所以更能反映出三种操作类型的性能差异。我们对属性直接进行赋值和取值是最快的,这一点没有什么好说的。我们关心的是,IL Emit的方式和单纯使用PropertyInfo进行反射(并且值得一提的是:PropertyInfo之前已经保存起来,并没有频繁去创建)的方式这两者的性能依然有本质的差别。如果你对数字不是敏感,那就看看下面的曲线图吧。
  五、PropertyAccessor的ExpressionTree版本()
  对于很多人来说,IL Emit编程是一件很繁琐的事。反正我多这比较头疼,我一般的做法都是将需要的逻辑通过代码写出来,编译之后跟据IL写Emit代码。而我们更喜欢采用的则是ExpressionTree,为此我编写了PropertyAccessor的ExpressionTree版本(你可以从下载)。两个版本主要的不同还是在于上述两个方法:CreateGetFunction和CreateSetAction。下面是两个方法的定义:
private Func&object, object& CreateGetFunction(){
var getMethod = this.Property.GetGetMethod();
var target = Expression.Parameter(typeof(object), "target");
var castedTarget = getMethod.IsStatic ? null : Expression.Convert(target, this.TargetType);
var getProperty = Expression.Property(castedTarget, this.Property);
var castPropertyValue = Expression.Convert(getProperty, typeof(object));
return Expression.Lambda&Func&object, object&&(castPropertyValue, target).Compile();} private Action&object, object& CreateSetAction(){
var setMethod = this.Property.GetSetMethod();
var target = Expression.Parameter(typeof(object), "target");
var propertyValue = Expression.Parameter(typeof(object), "value");
var castedTarget = setMethod.IsStatic ? null : Expression.Convert(target, this.TargetType);
var castedpropertyValue = Expression.Convert(propertyValue, this.PropertyType);
var propertySet = Expression.Call(castedTarget, setMethod, castedpropertyValue);
return Expression.Lambda&Action&object, object&&(propertySet, target, propertyValue).Compile();}
.NET技术热门文章
.NET技术最新文章查看:3315|回复:5
助理工程师
就是类似于这样
(assign) ClassA a[10];
这个ClassA是C++类,似乎无法放入NSArray中,我只好将其定义为数组
助理工程师
@property不能使用数组,可以用指针
不过我觉得不一定非要用
助理工程师
那我想生成getter或setter方法咋办 为了能够从外部导入数据
助理工程师
直接访问数组就好了,没必要非用getter/setter
助理工程师
支持!我也是用的指针!
助理工程师
用vector&classA&

我要回帖

更多关于 html property属性 的文章

 

随机推荐