使用 forin 遍历对象:
每次循环,会把对象中的一个字符串类型的属性名保存到变量key中。 (可以使用 consolelog(typeof key); 验证)
为什么objkey会输出undefined呢?是因为它被转换为obj["key"]后去obj中去找属性名为“key”的值,而不是把key识别为一个变量,在obj中并没有定义属性“key”,所以是undefined。
那现在给obj添加属性“key”:
会发现每次循环输出属性名为“key”的属性值。
使用 forin 变量对象时若其 原型 上有 自定义属性 也会拿到。
那如果不想要输出原型上的属性,只要自身属性怎么做呢?
hasOwnProperty(“属性名”)可以验证属性是否为对象本身所具有,返回布尔值。
上面循环改为
“属性名” in 对象 判断对象是否有这个属性(包括原型上的属性),即对象是否能访问到这个属性,返回布尔值。
A instanceof B 判断A对象的原型链上是否有B的原型对象。
写了个例子给你哈,这样做就可以用FOR循环遍历枚举的每个值了 class Program
{
enum days
{
Monday,
Saturday,
Wednesday,
Thursday,
Friday,
Tuesday,
Sunday
}
public static void Main(string[] args)
{
Type week=typeof(days);
Array Arrays = EnumGetValues(week);
for(int i=0;i<ArraysLongLength;i++)
ConsoleWriteLine(ArraysGetValue(i));
ConsoleWrite("Press any key to continue ");
ConsoleReadKey(true);
}
}
var obj = {name:"张三",age:18}
for(var key in obj){
consolelog("key:" + key + ",value:" + obj[key]);
}
//输出:key:name,value:张三和key:age,value:18
//这里的可枚举性就是说for的这种写法可以得到这个对象的属性名
var obj1 = {};
ObjectdefineProperties(obj1, {
name: {
value: "张三",
enumerable: false
},
age: {
value: 18,
enumerable: false
}
});
for(var key in obj1){
consolelog("key:" + key + ",value:" + obj[key]);
}
//这里不会输出任何东西,但是可以用obj1name和obj1age直接取值。
//当然obj1["name"]也是可以得到张三的。
//但是不能用for来枚举出他有什么属性。
//以上代码请在chrome或者火狐里面运行,IE9以下运行第二段代码会出错
由于JavaScript并没有提供enum关键字来建造枚举对象,所以前端一直有很多硬编码,这是非常不能令人容忍的,特别是在vue这种本身就代表优雅的框架开发下。
首先说明,目前是不能使用enum关键字来声明枚举,以下方式是个人自己编写,也是本人觉得较为优雅的方式,由于ES6的限制,声明方式也不完全像java中的enum
将如下Enumjs放入项目,随便想放哪个目录就放哪个目录,依据项目结构而定,我的话放在common下
根据个人编码习惯,我喜欢把枚举类单独放在一个文件夹下,这样便于统一管理,比如我就统一放在项目目录下的env文件夹下
举例:创建 UserStatusEnumjs 引入Enumjs,创建UserStatusEnum类并继承Enum类
这里要注意的是,枚举对象要使用数组,属性上下顺序对应枚举中数组内容的顺序,比如这里code在desc上面,那么就分别对应NORMAL中的一二位,这点会java的同学应该一目了然,当然,如果有多个填写多个属性便是,如果是没有属性的记得枚举那里也要写成数组形式,只是不填值便可
打开控制台可以看到枚举对象已经创建好了,直接食用便可
例:
枚举用于声明一组命名的常数,当一个变量有几种可能的取值时,可以将它定义为枚举类型。
任意两个枚举成员不能具有相同的名称
在枚举类型中声明的第一个枚举成员它的默值为0
允许多个枚举成员有相同的值
没有显示赋值的枚举成员的值,总是前一个枚举成员的值+1
eg:
public enum Number
{
a=1,
b,
c=1,
d
} ;
b的值为2,d的值为2
这个我可能要解释一些编译原理范畴的东东了。我首先抛掉虚函数那一块,就考虑一个普通的c++类。Class A{ int a, int b, char c, short d; };现在的问题是能不能枚举它的a,b,c,d属性?
我首先给出答案,不能。 java应该是可以的,python也是可以的,这些东西的前提都有一个类对象的概念。何为类对象,也就是A这个类本身也是一个对象,这个类对象来存储A这个类的所有属性,所有函数。 只能这个类对象,才有java里面的反射一说,何为反射,给出对象以及函数的字符串,它就可以调用函数。也就是说能够根据字符串直接在运行时找到对应的函数指针,这在c++中如果没有预先存储好字符串和函数的映射中,是无法完成的。 java中它可以遍历这个类对象(我猜的,当然存个hash也行)逐个函数名字看,如果匹配就返回对应的函数指针,同样的,属性也一样。 C++就不同了,c++中只存对象,也就是说A a;这样的一句话,编译器只会编译出来一个创建a对象的指令集。然后在运行的时候,当运行到A obj;这一堆指令的时候,就开始分配内存能够放下这4个属性就ok了(这些指令集都是预先编译完成的,运行的时候它可不管属性是a,还是b)。那你可能会问了,如果用户obja = 10;那么是如何赋值的呢? 其实还是编译器在作怪,它在编译的时候看到objb = 10,它编译的时候能够看到A的结构,知道b位于obj的第4-8个字节,它在前面的编译出来的指令中假设有一个寄存器存储着obj的地址为EAX,那么这个时候只需要进行mov [EAX+4] 10,就是这样的一条指令把10赋值给了EAX+4指向的地址中4个字节里面(指令大概是这样,具体汇编会有差异,思想一致)。 也就是说编译器编译后直接写死了这条指令,它运行的时候根本不知道实际干的是obja = 10,还是其他。 同理,它运行的时候都看不到了a,b,c,d这些属性,又如何能通过遍历看到它们呢?或者换句话说,它遍历什么东西才能看到a,b,c,d呢?在运行的时候,它压根不知道EAX存的obj的地址,它仅仅傻白甜的执行着一条条的指令序列。
Swift基础语法总结,来自 苹果官方文档 :
枚举在Swift中是 first-class types。与C,Objective-C中的枚举相比,Swift中枚举功能更强大。它支持很多只有类才有的特性,如: Properties , Methods , Initialization , Extensions , Protocols
举例:
通常将单个枚举值与switch语句匹配:
当需要迭代枚举中的所有情况时,需要自定义的枚举遵守 CaseIterable 协议
我们可以定义Swift枚举来存储任何给定类型的关联值,而且每种枚举情况的值类型可以不同。
可以将关联值提取为switch语句的一部分。将每个关联值提取为常量(let)或变量(var),以便在switch中处理:
如果枚举case的所有关联值都被提取为常量,或者都被提取为变量,则可以将var或let放置在case名称前面,来提取所有的关联值:
“ 关联值 ”表明了枚举如何存储不同类型的关联值。作为关联值的替代,枚举情况可以预先设置默认值(称 原始值 ),它们都是相同的类型。
原始值可以是字符串,字符,整数或浮点数类型。每个原始值在其枚举声明中必须是唯一的。
当使用存储整数或字符串原始值的枚举时,不必为每种case显式分配原始值,Swift将自动为其分配值。如果使用整数为原始值,则每个case的原始值依次自增1。若第一个case没有设置原始值,则默认为0:
当使用字符串作为原始值时,每个case的隐含值是该case的名称。
使用枚举的 rawValue 属性来访问其原始值:
如果使用原始值类型定义枚举,则枚举会自动接收一个带有原始值的初始化器,并返回可选类型的枚举实例。
递归枚举是将枚举的另一个实例作为一个或多个枚举case的关联值。在枚举case 前面添加关键字 indirect 来指明该枚举case是递归的,这就告诉了编译器插入必要的间接层。
例如,下面是存储简单算术表达式的枚举:
还可以在枚举 enum 之前添加 indirect ,以便为所有具有关联值的枚举case启用间接:
递归函数是处理具有递归结构的数据的简单方法。例如,这是一个计算算术表达式的函数:
Swift 42 基础专题详解
以上就是关于对象的枚举(for in、hasOwnProperty、in、instanceof)全部的内容,包括:对象的枚举(for in、hasOwnProperty、in、instanceof)、C#中,定义了一个枚举,怎么用for循环来遍历枚举中的每个值、JavaScript属性可枚举性谁能给我解释下什么叫做属性的可枚举性,谢谢了等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)