美文网首页
定义一个变量

定义一个变量

作者: yanghanbin_it | 来源:发表于2017-06-09 10:23 被阅读0次

属性描述符(Property Descriptors)

var myObject = {
    a: 2
};

Object.getOwnPropertyDescriptor( myObject, "a" );
// {
//    value: 2,
//    writable: true,
//    enumerable: true,
//    configurable: true
// }

我们普通的对象属性a的属性描述符(称为“数据描述符”,因为它仅持有一个数据值)的内容要比value为2多得多。它还包含另外3个性质:writable,enumerable,和configurable。

可写性(Writable)

writable控制着你改变属性值的能力。

var myObject = {};

Object.defineProperty( myObject, "a", {
    value: 2,
    writable: false, // 不可写!
    configurable: true,
    enumerable: true
} );

myObject.a = 3;

myObject.a; // 2

我们对value的修改悄无声息地失败了

可配置性(Configurable)

只要属性当前是可配置的,我们就可以使用同样的defineProperty(..)工具,修改它的描述符定义。

var myObject = {
    a: 2
};

myObject.a = 3;
myObject.a;                    // 3

Object.defineProperty( myObject, "a", {
    value: 4,
    writable: true,
    configurable: false,    // 不可配置!
    enumerable: true
} );

myObject.a;                    // 4
myObject.a = 5;
myObject.a;                    // 5

Object.defineProperty( myObject, "a", {
    value: 6,
    writable: true,
    configurable: true,
    enumerable: true
} ); // TypeError

最后的defineProperty(..)调用导致了一个TypeError,这与strict mode无关,如果你试图改变一个不可配置属性的描述符定义,就会发生TypeError。要小心:如你所看到的,将configurable设置为false是 一个单向操作,不可撤销!

注意: 这里有一个需要注意的微小例外:即便属性已经是configurable:false,writable总是可以没有错误地从true改变为false,但如果已经是false的话不能变回true。

configurable:false阻止的另外一个事情是使用delete操作符移除既存属性的能力。

对象常量(Object Constant)

通过将writable:false与configurable:false组合,你可以实质上创建了一个作为对象属性的 常量(不能被改变,重定义或删除),比如:

var myObject = {};

Object.defineProperty( myObject, "FAVORITE_NUMBER", {
    value: 42,
    writable: false,
    configurable: false
} );

防止扩展(Prevent Extensions)

如果你想防止一个对象被添加新的属性,但另一方面保留其他既存的对象属性,调用Object.preventExtensions(..):

var myObject = {
    a: 2
};

Object.preventExtensions( myObject );

myObject.b = 3;
myObject.b; // undefined

封印(Seal)和 冻结(Freeze)

Object.seal(..)创建一个“封印”的对象,这意味着它实质上在当前的对象上调用Object.preventExtensions(..),同时也将它所有的既存属性标记为configurable:false。
所以,你既不能添加更多的属性,也不能重新配置或删除既存属性(虽然你依然 可以 修改它们的值)。

Object.freeze(..)创建一个冻结的对象,这意味着它实质上在当前的对象上调用Object.seal(..),同时也将它所有的“数据访问”属性设置为writable:false,所以他们的值不可改变。

存在性(Existence)

in和hasOwnPrototype

in操作符会检查属性是否存在于对象中,或者是否存在于[[Prototype]]链对象遍历的更高层中。
相比之下,hasOwnProperty(..) 仅仅 检查myObject是否拥有属性,但不会查询[[Prototype]]链

var myObject = {
    a: 2
};

("a" in myObject);                // true
("b" in myObject);                // false

myObject.hasOwnProperty( "a" );    // true
myObject.hasOwnProperty( "b" );    // false

枚举(Enumeration)

var myObject = { };

Object.defineProperty(
    myObject,
    "a",
    // 使`a`可枚举,如一般情况
    { enumerable: true, value: 2 }
);

Object.defineProperty(
    myObject,
    "b",
    // 使`b`不可枚举
    { enumerable: false, value: 3 }
);

myObject.b; // 3
("b" in myObject); // true
myObject.hasOwnProperty( "b" ); // true

// .......

for (var k in myObject) {
    console.log( k, myObject[k] );
}

你会注意到,myObject.b实际上 存在,而且拥有可以访问的值,但是它不出现在for..in循环中(然而令人诧异的是,它的in操作符的存在性检查通过了)。这是因为“enumerable”基本上意味着“如果对象的属性被迭代时会被包含在内”。

Object.keys()和Object.getOwnPropertyNames() 、propertyIsEnumerable

1.Object.keys()返回一个所有可枚举属性的数组,而Object.getOwnPropertyNames()返回一个 所有 属性的数组,不论能不能枚举。

2.propertyIsEnumerable()测试一个给定的属性名是否直 接存 在于对象上,并且是enumerable:true。

var myObject = { };

Object.defineProperty(
    myObject,
    "a",
    // 使`a`可枚举,如一般情况
    { enumerable: true, value: 2 }
);

Object.defineProperty(
    myObject,
    "b",
    // 使`b`不可枚举
    { enumerable: false, value: 3 }
);

myObject.propertyIsEnumerable( "a" ); // true
myObject.propertyIsEnumerable( "b" ); // false

Object.keys( myObject ); // ["a"]
Object.getOwnPropertyNames( myObject ); // ["a", "b"]

in和hasOwnProperty(..)区别于它们是否查询[[Prototype]]链,而Object.keys(..)和Object.getOwnPropertyNames(..)都 只 考察直接给定的对象。

相关文章

  • C语言基础

    C语言定义变量 定义一个变量 给变量赋值 定义一个变量的同时给变量赋值 C语言使用变量之前必须赋值或者初始化 试试...

  • 环境变量与文件查找

    变量的定义 使用命令declare $定义一个新变量 declare $test 定义一个名为test的新变量。或...

  • shell之自定义变量

    定义变量 定义变量时,变量名称前不加$号 注意事项image.png 使用变量 使用一个定义过的变量,只要在变量名...

  • go-基础语法

    一、定义变量 1.先定义再赋值 2.定义的同时并赋值 3定义多个变量 二、自动推导 如果定义一个变量,并直接赋值,...

  • Python局部变量详解(含义、作用、生命周期)

    定义: 局部变量是在函数内部定义的变量,只能在函数内部使用。 全局变量是在函数外部定义的变量(没有定义在某一个函数...

  • C++变量类型

    C++ 中的变量定义 变量定义 :告诉编译器在何处创建变量的存储,以及如何创建变量的存储。变量定义指定一个数据类型...

  • C++变量类型

    C++中变量的定义与声明 变量定义就是告诉编译器在何处创建变量的存储,以及如何创建变量的存储。变量定义指定一个数据...

  • PHP面试题61-80

    变量如何定义?如何检查变量是否定义?如何删除一个变量?判断一个变量是否为空的函数?isset()unset()em...

  • 星号的三种用法

    乘法 定义指针变量,例如int * a;定义了一个指针变量a 间接运算符,放在已经定义好的指针变量前,如果a是一个...

  • PHP易混淆知识点大分享-连载1

    变量如何定义?如何检查变量是否定义?如何删除一个变量?怎样检测变量是否设置? 什么是可变变量? 变量赋值方式有哪几...

网友评论

      本文标题:定义一个变量

      本文链接:https://www.haomeiwen.com/subject/spctqxtx.html