首页 未命名正文

linux编程_深入明白JavaScript中的属性和特征

云返利网 未命名 2020-05-26 09:06:08 8 0

JavaScript中属性和特征是完全差别的两个观点,这里我将凭据自己所学,来深入明白JavaScript中的属性和特征。

  主要内容如下:

明白JavaScript中明白工具的本质、明白工具与类的关系、工具与引用类型的关系
工具属性若何举行分类
属性中特征的明白
 

第一部门:明白JavaScript中明白工具的本质、明白工具与类的关系、工具与引用类型的关系
   工具的本质:ECMA-262把工具界说为:无序属性的聚集,其属性可以包罗基本值、工具或者函数。即工具是一组没有特定顺序的值,工具的每个属性或方式都有一个名字,而这个名字都映射到一个值。故工具的本质是一个散列表:其中是一组名值对,值可以是数据或函数。

   工具和类的关系:在JavaScript中,工具和类没有任何关系。这是由于ECMAScript中根本就没有类的观点,它的工具与其他基于类的语言中的工具是差别的。

   工具和引用类型的关系:工具和引用类型并不是等价的,由于每个工具都是基于一个引用类型建立的。

第二部门:工具属性若何举行分类
  由组织函数或工具字面量方式建立的工具中具有属性和方式(只要提到属性和方式,它们一定是属于工具的;只要提到工具,它一定是具有属性和方式的(自界说除外)),其中属性又可分为数据属性和接见器属性,他们的区别如下:

数据属性一样平常用于存储数据数值,接见器属性不包罗数据值
接见器属性多用于get/set操作
 

第三部门:属性中特征的明白
  ECMAScript为了形貌工具属性(property)的种种特征,界说了特征(attribute)这个观点。也就是说特征差别于属性,特征是为了形貌属性的。下面,我将划分解说:

数据属性及其特征
接见器属性及其特征
若何行使Object.defineProperties()方式界说多个特征
若何行使Object.getOwnPropertyDescripter()方式读取属性的形貌符以读取属性的特征
1.数据属性及其特征

  刚刚我们说过,数据属性是用于存储数据数值的,因此数据属性具有一个数据值的位置,在这个位置可以读取和写入值。数据属性有4个形貌其行为的特征,由于ECMAScript划定:在JavaScript中不能直接接见属性的特征(注重:不是不能接见),以是我们把它放在两组方括号中。如下:

[[Configurable]]:默认值为true,a、示意能否通过delete删除属性从而重新界说属性 b、能否修改属性的特征 c、能够把属性由数据属性修改为接见器属性
[[Enumerable]]:默认值为true,示意能否通过for-in循环返回该属性(以是:若是为false,那么for-in循环没法枚举它所在的属性)
[[Writable]]:默认值为true,示意能否修改属性的值,这是与[[Configurable]]差别之处。
[[Value]]:默认值为undefined,这个值即为属性的属性值,我们可以在这个位置上读取属性值,也可以在这个位置上写入属性值。
注重:上述的默认是指通过组织函数或工具字面量建立的工具所自身拥有的属性,而不是下面要先容的Object.defineProperty()方式
这些特征都具有默认值,然则若是这些默认值不是我们想要的,该怎么办呢?固然就是修改啦!我们可以通过Object.defineProperty()方式来修改属性默认的特征。英文difineProperty即为界说属性的意思。这个方式吸收三个参数:属性所在的工具、属性的名字和一个形貌符工具。其中第三个参数形貌符工具是工具字面量的方式建立的,内里的属性和属性值实际上保留的是要修改的特征和特征值。

下面通过几个例子来深入明白。

a

        var person={};
Object.defineProperty(person,"name",{
    writable:false,
    value:"zhuzhenwei"
});
console.log(person.name);//zhuzhenwei
person.name="heting";
console.log(person.name);//zhuzhenwei

  这里我用工具字面量的方式建立了一个工具,然则没有同时建立方式和属性。而是行使了Object.defineProperty()方式来建立了属性和修改了默认值。这里将writable设置为false,于是后面我试图修改person.name时,是无效的。

b

        var person={};
Object.defineProperty(person,"name",{
    value:"zhuzhenwei"
});
console.log(person.name);//zhuzhenwei
person.name="heting";
console.log(person.name);//zhuzhenwei

  注重看这个例子,这个例子中我删去了writable:false,为什么照样不能修改呢?这是由于之前我在先容特征时,前三个默以为ture,是在建立工具并建立属性的情况下获得的。对于通过挪用Object.defineProperty()方式建立的属性,其前三个特征的默认值均为false,这里需要注重。

 c

var person={};
Object.defineProperty(person,"name",{
    value:"zhuzhenwei",
    configurable:false
});
console.log(person.name);//zhuzhenwei
delete person.name;
console.log(person.name);//zhuzhenwei

  这里我们将新建的属性name的特征设置为了configurable:false;因此下面删除属性的操作是无效的。凭据b,可知configurable,默认就是false,纵然去掉也不能修改。

d

?
1
2
3
4
5
6
7
8 var person={};
Object.defineProperty(person,"name",{
    value:"zhuzhenwei",
    configurable:true
});
console.log(person.name);//zhuzhenwei
delete person.name;
console.log(person.name);//undefined

  在这里我将默认的configurable的值由默认的false修改为了true,于是变成了可设置的,那么最后就乐成删除了。

e

        var person={};
Object.defineProperty(person,"name",{
    value:"zhuzhenwei",
    configurable:false
});
console.log(person.name);//zhuzhenwei
Object.defineProperty(person,"name",{
    value:"zhuzhenwei",
    configurable:true
});
console.log(person.name);//Uncaught TypeError: Cannot redefine property: name(…)

  若是之前已经设置成为了false,那么后面再改成true也是徒劳的,即:一旦把属性设置成为不能设置的,就不能再把它变回可设置了。

f

console.log(person.name);//Uncaught TypeError: Cannot redefine property: name(…)
var person={};
Object.defineProperty(person,"name",{
    value:"zhuzhenwei",
});
console.log(person.name);//zhuzhenwei
Object.defineProperty(person,"name",{
    value:"zhuzhenwei",
    configurable:true
});
console.log(person.name);//Uncaught TypeError: Cannot redefine property: name(…)

  这里可以说明,纵然前一步我们不管默认的configurable:false,后面获得的仍是不能设置。于是,可以得出结论,为了可设置,必须在第一次挪用Object.defineProperty()函数时就将默认的值修改为true。

 2.接见器属性及其特征  

   之前提到,接见器属性不包罗数据值,他们包罗一对getter函数和setter函数(这两个函数不是必须的)。在读取接见器属性时,会挪用getter函数,这个函数卖力返回有用的值;在写入接见器属性是,会挪用setter函数并传入新值,这个函数卖力决议若何处置数据。同样,由于不能通过JavaScript来直接接见获得接见器属性的特征,以是下面列出的特征将由[[]]括起来以作区分。

[[Configurable]]:默认值为true,a、示意能否通过delete删除属性从而重新界说属性 b、能否修改属性的特征 c、能够把属性由接见器属性修改为数据属性
[[Enumerable]]:默认值为true,示意能否通过for-in循环返回该属性(以是:若是为false,那么for-in循环没法枚举它所在的属性)
[[Get]]:在读取属性时挪用的函数。默认值为undefined  要害:特征可以是一个函数
[[Set]]:  在写入属性时挪用的函数。默认值为undefined 要害:特征可以是一个函数 由于get和set函数也属于属性的特征,那么他们就有可能(说有可能是由于这两个函数也不是必须的)出现在Object.defineproperty的第三个参数形貌符工具的属性中。
注重:1.相对于数据属性,我们发现接见器属性中没有writable特征和value特征。这是由于接见器属性不包罗数据值,那么我们怎么固然就不能修改属性的值(用不到writable特征),更不用思量value了。

   2.接见器属性不能直接界说,必须是用Object.defineProperty()来界说。(通过这个划定我们就能准确地判断出接见器属性和数据属性了)

通过下面这个例子来深入明白:

var book={
    _year:2004,
    edition:1
};
Object.defineProperty(book,"year",{
    get:function(){<br>            return this._year;
    },
    set:function(newValue){
        if(newValue>2004){
            this._year=newValue;
            this.edition+=newValue-2004;
        }
    }
});
book.year=2005;
console.log(book.edition);//2

几个需要深入明白的地方:

接见器属性不能直接界说,必须使用Object.defineProperty()来界说,且该属性具有set和ger特征,于是可以判断,_year和edition是数据属性,而year是接见器属性。
我们看到_year这个数据属性前面是以_(下划线)开头的,这个一种常用的记号,用于示意只能通过工具方式接见的属性。从上面的例子中可以看到get相当于形貌符工具的一个方式,而_year正是在这个工具方式接见的属性。而edition既可以通过工具方式接见,也可以由工具直接接见。
?

book.year示意正在读取接见器属性,这时会挪用get函数,并返回了2004这个有用的值。
book.year=2005示意写入接见器属性,这时会挪用set函数并传入新值,即将2005传给newValue,这个函数决议若何处置数据。
这时使用接见器属性的常见方式-即设置一个属性的值会导致其他属性发生变化。

3.若何行使Object.defineProperties()方式界说多个特征

 显然,一个工具不能能只具有一个属性,因此,界说多个属性的可能性很大,于是JavaScript提供了Object.defineProperties()方式解决这个问题。这个方式吸收两个参数,第一个是要界说属性所在的工具,第二个是一个工具字面量方式建立的工具,工具的属性名即为要界说的特姓名,工具的属性值又是一个工具,这个工具里的属性名和属性值划分是特征名和特征值(这里不是很好明白,看例子即可)。

var book={};
Object.defineProperties(book,{
    _year:{
        writable:true,
        value:2004
    },
    edition:{
        writable:true,
        value:1
    },
    year:{
        get:function(){
            return this._year;
        },
        set:function(){
            if(newValue>2004){
                this._year=newValue;
                this.edition+=newValue-2004;
            }
        }
    }
});

4.若何行使Object.getOwnPropertyDescripter()方式读取属性的形貌符以读取属性的特征

  我们可以使用Object.getOwnPropertyDescripter()方式来取得给定属性的形貌符。getOwnPropertyDescripter即为取得自身属性形貌符的意思。这个方式吸收两个参数:属性所在的工具要要读取其形貌符的属性名称。返回一个工具。

  对于接见器属性而言,这个工具的属性有configurable、enumerable、get和set;

  对于数据属性而言,这个工具的属性有configurable、enumerable、writable和value。

var book={};
Object.defineProperties(book,{
    _year:{
        value:2004
    },
    edition:{
        value:1
    },
    year:{
        get:function(){
            return this._year;
        },
        set:function(){
            if(newValue>2004){
                this._year=newValue;
                this.edition+=newValue-2004;
            }
        }
    }
});
var descriptor=Object.getOwnPropertyDescriptor(book,"_year");
console.log(descriptor.value);//2004
console.log(descriptor.configurable);//false  由于通过Object.defineProperties()方式建立的属性的特征configurable enumerable都是false
console.log(typeof descriptor.get);//undefined 注重:这是数据属性,是不具有get特征的
 
var descriptor=Object.getOwnPropertyDescriptor(book,"year");
console.log(descriptor.value);//undefined
console.log(descriptor.enumerable);//false
console.log(typeof descriptor.get);//function get

【关于云返利网】

云返利网是阿里云、腾讯云、华为云产品推广返利平台,在各个品牌云产品官网优惠活动之外,云返利网还提供返利。您可以无门槛获得阿里云、华为云、腾讯云所有产品返利,在官网下单后就可以领取,无论是自己用、公司用还是帮客户采购,您个人都可以获得返利。云返利网的目标是让返利更多、更快、更简单!详情咨询13121395187(微信同号)