js知识梳理一,js权威指南学习笔记

By admin in 4858美高梅 on 2019年4月16日

写在头里

注:那几个体系是自作者对js知识的1对梳理,个中不少情节出自书籍:Javascript高等程序设计第二版和JavaScript权威指南第四版,谢谢它们的撰稿人和翻译。有觉察怎么难题的,欢迎留言提议。

知晓对象

一、创造对象

面向对象(Object-Oriented,OO)的言语有3个标明,那正是它们都有类的定义,而经过类能够创立任意几个具备一样属性和方法的对象.

壹.数额属性

数据属性的6个特性:

  • Configurable:1意味是不是通过delete删除属性从而再次定义,二是不是修改属性的特点,3是还是不是把质量修改为访问器属性。对象直接量里暗中同意值true。
  • Enumerable:表示能还是不能够通过for-in循环重返属性。对象直接量里暗中认可值true。
  • Writable:表示能或不能够修改属性的值。对象间接量里暗许值true。
  • Value:包蕴那特性格的数据值。对象直接量里私下认可值undefined。

//查看对象直接量的属性的属性特性默认值
var people = {
    name:'jaychou',
    sayName:function () {
        console.log(this.name);
    }
};
/**{value: "jaychou", writable: true, enumerable: true, configurable: true}*/
console.log(Object.getOwnPropertyDescriptor(people,'name'));
/**{value: ƒ, writable: true, enumerable: true, configurable: true}*/
console.log(Object.getOwnPropertyDescriptor(people,'sayName'));
//getOwnPropertyDescriptor对于继承属性和不存在的属性,返回undefined

要修改属性默许的性状,使用Object.defineProperty()方法,接收二个参数:对象,属性名字和讲述符对象。

//修改属性默认特性:
Object.defineProperty(person,'job',{
    emumerable:false,//不可枚举
    value:'singer',
    writable:false,//不可写
    configurable:true
});
/**{name: "jaychou", sayName: ƒ, job: "singer"}*/
console.log(person);
for(var prop in person){
    //打印name,sayName
    console.log(prop);
}
//会报错
try{
    person.job = 'director';
}catch (e) {
    //Cannot assign to read only property 'job' of object
    console.log(e);
}

能够频仍调用Object.defineProperty()方法修改同一特品质,但在把configurable天性设置为false之后就会有限定了:

Object.defineProperty(person,'height',{
    configurable:false,//不可配置
    writable:true,
    value:172
});
try{
    Object.defineProperty(person,'height',{
        configurable:true,//出错
        enumerable:true,//出错
        value:175,//正常
        writable:false,//writable从true变false可以,false变true也会出错
    });
}catch (e) {
    //Cannot redefine property: height at Function.defineProperty
    console.log(e);
}
try{
    delete person.height;
}catch (e) {
    //设置成不可配置后也不可删除:Cannot delete property 'height' of #<Object>
    console.log(e);
}

其它,调用
Object.defineProperty()方法时,倘使不点名,configurable、enumerable 和
writable 本性的私下认可值都以 false。倘若是修改已有总体性,则无此限制。


(壹)、通过对象直接量的艺术开创

ECMAScript中一直不类的概念,由此它的目的也与基于类的言语中的对象有所不相同.

贰.囤积器属性

仓库储存器属性不含有数据值,只含有包蕴 getter 和 setter 函数(非必需)。
在读取存款和储蓄器属性时,会调用 getter
函数,那一个函数负责重返有效的值;在写入存款和储蓄器属性时,会调用 setter
函数并传播新值,那一个函数负责调整哪些处理多少。6个天性性格如下:

  • Configurable:1意味是不是通过delete删除属性从而再一次定义,贰能或无法修改属性的特点,三是不是把质量修改为数量属性。对象直接量的暗中认可值true
  • Enumerable:表示能或不可能通过for-in循环再次回到属性。对象间接量的私下认可值true
  • Get:在读取属性时调用的函数。对象直接量私下认可值undefined
  • Set:在写入属性时调用的函数。对象直接量的暗中认可值undefined

概念存储器属性最简便易行的艺术是运用对象间接量语法的举行写法:

var p = {
    x:3.0,
    y:4.0,
    //r是可读写的存取器属性
    get r(){return Math.sqrt(this.x*this.x+this.y*this.y);},
    set r(newValue){
        var oldvalue = Math.sqrt(this.x*this.x+this.y*this.y);
        var ratio = newValue/oldvalue;
        this.x *= ratio;
        this.y *= ratio;
    },
    //theta是只读存取器属性
    get theta(){return Math.atan2(this.y,this.x);}
}
console.log(p.r);
p.r = 25;

利用Object.defineProperty()方法定义存款和储蓄器属性:

var book = {
    _year:2004,
    edition:1
};
Object.defineProperty(book,"year",{
    get:function () { return this._year; },
    set:function (newValue) {
        if(newValue>2004){
            this._year = newValue;
            this.edition += newValue - 2004;
        }
    }
})
/**{get: ƒ, set: ƒ, enumerable: false, configurable: false}*/
console.log(Object.getOwnPropertyDescriptor(book,'year'));

如例子所示,使用存款和储蓄器属性的周边格局,即设置二天性质的值会导致其余属性产生变化。还有壹种常见就是当今盛行的近乎于Vue的响应式原理,正是把data中的属性都应用defineProperty修改为存款和储蓄器属性,能够监听到多少的扭转。

开创自定义对象的最简便方法就是创制三个Object的实例,然后再为它增添属性和措施

注脚:对象直接量是由若干名/值对构成的映射表,名/值对中级用冒号分隔,名/值对中间用逗号分隔,整个映射表用花括号括起来。

ECMA-26贰把目的定义为:”冬辰属性的集结,其属性能够涵盖基本值,对象恐怕函数”.

三.概念多少个属性

平常要创造或修改多少个属性,那时候能够动用Object.defineProperties()方法,它接受三个参数,要增加或涂改属性的对象和1个映射表,包蕴名称和个性描述符。

var book1 = {};
Object.defineProperties(book1,{
   _year:{
       value:'2008'
   },
   editor:{
       enumerable:true,
       value:'2'
   },
   year:{
       get:function () {
           return this._year;
       },
       set:function (newValue) {
           this._year = newValue;
           this.edition += newValue - 2004;
       }
   }
});
1     var person = new Object();
2     person.name = "Nicholas";
3     person.age = 29;
4     person.job = "SoftWare Engineer";
5     person.sayName = function(){
6         alert(this.name);
7     };

如:

严加来讲,那就一定于说对象是一组并未有特定顺序的值.对象的各种属性或措施都有3个名字,而各种名字都映射到叁个值.正因为这么,我们得以把EMCAScript的靶子想象成散列表:无非正是1组名值对,个中值能够是多少或函数.

四.对象的可扩充性

对象的可拓展性表示是还是不是足以给指标增添新属性。全部内置对象和自定义对象都以显式可增加的,宿主对象的可扩充性是由Javascript引擎定义的。

 

 

种种对象老师基于1个引用类型创立的,那些引用类型能够是此前钻探的原生类型,也能够是开辟人士定义的类型.

一.询问对象可拓展性
var teacher = {age:25};
//true:代表可拓展
console.log(Object.isExtensible(teacher));

创设对象的主要推荐方式是目的字面量方式

 

6.壹 驾驭对象

2.转移为不可拓展(“锁定目的”)
Object.preventExtensions(teacher);
//false
console.log(Object.isExtensible(teacher));
try{
    teacher.subject = 'math';
}catch (e) {
    //TypeError: Cannot add property subject, object is not extensible
    console.log(e);
}

调换到不可拓展的操作是不可逆的,而且不得不影响到指标自我的可拓展性,假如给四个不行拓展目的的原型增加属性,这么些不可拓展指标同样会继续那么些新属性。

1     var person = {
2         name: "Nicholas",
3         age: 29,
4         job: "SoftWare Engineer",
5         sayName: function(){
6             alert(this.name);
7         }
8     };

 

成立自定义对象的最简易就是创办三个Object的实例,然后再为它增添属性和方法.

5.密封目的

密封对象比锁定指标更加高壹层,除了不足拓展以外,对象的兼具自己性质都设置成了不足配置的。一样密封对象操作是不可逆的。

var tea1 = {subject:'math'};
//false:代表未密封
console.log(Object.isSealed(tea1));
Object.seal(tea1);
try{
    Object.defineProperty(tea1,'subject',{
        //enumerable:false,//出错
        //configurable:true,//出错
        writable:false//和上面说的一样,writable从true变成false可以,false变成true则出错
    });
}catch (e) {
    console.log('出错..');
    console.log(e);
}
//true:已密封
console.log(Object.isSealed(tea1));

 

 

var person=new Object();
    person.name="Nicholas";
    person.age=29;
    person.job="Software Engineer";

    person.sayName=function(){
        alert(this.name);
    };

6.冷冻对象

凝冻比密封对象多的效用是:能够将它自有的具有数据属性设置为只读(借使目的的存取器属性具备setter方法,存取器属性将不受影响,还能够经过给属性赋值调用它们)。

var tea2 = {subject:'Chinese'};
//false:代表未冻结
console.log(Object.isFrozen(tea2));
Object.freeze(tea2);
try{
    tea2.subject = 'math';
}catch (e) {
    //TypeError: Cannot assign to read only property 'subject' of object
    console.log(e);
}
//true:已冻结
console.log(Object.isFrozen(tea2));

属性类型

5

最初人士平日使用那种创设三个名对象,并为它增多多少个属性和方法.之后,对象字面量成为开创那种对象的首要推荐形式.

7.属性天性规则总计

  • 假如指标是不可拓展的,则足以编写制定已有个别自有总体性,但不可能给它丰盛新属性。
  • 壹旦属性是不足配置的,则不可能修改它的可配置性和可枚举性。
  • 借使存取器属性是不行配置的,则不可能改改其getter和setter方法,也不能够将它转换为数量属性。
  • 假定数额属性是不行配置的,则不可能将它调换为存取器属性。
  • 万一数量属性是不可配置的,则不可能将它的可写性从false修改为true,但足以从true修改为false。
  • 假使数额属性是不行配置且不可写的,则不能够改改它的值。但是可配备但不可写属性的值是能够修改的(做法:先将它标记为可写的,然后修改它的值,最终调换为不可写的)。

 

5

var person={
        name:"Nicholas",
        age:29,
        job:"Software Engineer",

        sayName:function(){
            alert(this.name);
        }

 

其壹例子中的person对象与日前例子中的person对象一样的,都有同一的品质和方法.那么些属性在开马上都带有①些特征值(characteristic),JavaScript通过那几个特色值来定义它们的行为.

js知识梳理一,js权威指南学习笔记。 

 

六.1.一性质类型

中间属性不可能间接待上访问,ECMAScript伍把它们位于两对方括号中,分为数据属性和走访器属性

 

ECMA-26贰第四版在概念只有个中都用的天性(attribute)时,描述了质量(property)的种种特征.ECMA-26二定义这一个特征是为了贯彻JavaScript引擎用的,由此在JavaScript中不能够直接待上访问它们.为了表示特征是内部值,该专业把它们位于了两对儿方括号中,例如[[Enumerable]].

一、数据属性

 

ECMAScript中有二种属性:数据属性和做客器属性.

多少属性包罗二个数据值的职分。在那么些任务能够读取和写入值。数据属性有八个描述其表现的性状

 

1.数额属性

[[Configurable]]:表示能或无法通过delete输出属性从而定义属性,能还是无法修改属性的表征,只怕是不是把品质修改为访问器属性,暗许值为true

1

数量属性包涵一个数据值的地方.在这么些职位能够读取和写入值.数据属性有5个描述其作为的个性.

[[Enumerable]]:表示能还是不能通过for-in循环再次来到属性,私下认可值为true

var empty = {}; //创建一个空对象

[[Configurable]]:表示是不是通过delete删除属性从而再一次定义属性,能还是不能够修改属性的性状,或许是不是把品质修改为访问器属性.像后边例子中那样间接在对象上定义的本性,它们这一个天性默许值为true.

[[Writable]]:表示能或无法通过改造属性的值,私下认可值为true

2

[[Enumerable]]:表示能还是无法通过for-in循环再次回到属性.像前边例子中那么直接在指标上定义的性质,它们的这么些特点暗许值为true.

[[Value]]:包罗这一个特性的数据值,读取属性值的时候,从那几个职分读;写入属性值的时候,把新值保存在那几个职位

var point = {

[[Writable]]:表示能或不能够修改属性的值.像前面例子中那么直接在目的上定义的性子,它们的那些特点私下认可值为true.

 

3

[[Value]]:包涵这一个天性的数据值.读取属性值的时候,从那么些任务读;写入属性值的时候,把新值保存在这些职位,那天性格的暗中同意值为undefined.

4858美高梅,要修改属性默许的性状,必须选取ECMAScript伍的Object.defineProperty()这么些方法.那一个艺术接受多少个参数:属性所在的靶子、属性的名字和3个叙述符对象

    x : 0,

对于像后边的例证中那么直接在目标上定义的习性,它们的[[Configurable]],[[Enumberable]]和[[Writable]]特点都被设置为true,而[[Value]]特征棉被服装置为钦点的值.

 

4

var person={
        name:"Nicholas"
    };
1     var person = {};
2     Object.defineProperty(person,"name",{
3         writable: false,//设置为不可修改属性的值
4         value: "Nicholas"
5     });
6 
7     console.log(person.name); // " Nicholas"
8     person.name = "Oreg";
9     console.log(person.name); // " Nicholas"
    y : "ccc

那边创办了一个名称为name的习性,为它钦点的值为”Nicolas”.也正是说,[[Value]]特色将被设置为”Nicolas”,而对那几个值的其余修改都将反映在那几个地方.

 

5

要修改属性暗中同意的风味,必须运用ECMAScript
伍的Object.defineProperty()方法.这几个方法接收八个参数:属性所在的对象,属性的名字和一个叙述符对象.当中,描述符(descriptor)对象的习性必须是:configurable,enumerable,writable和value.设置个中的3个或多少个值,能够修改对应的天性值.

 

}
var person={};
    Object.defineProperty(person,"name",{
        writable:false,
        value:"Nicholas"
    });

    alert(person.name);//Nicholas
    person.name="Greg";
    alert(person.name);//Nicholas

把donfigurable设置为false,表示不能从指标中删除属性。一旦把质量定义为不可配置的,就不可能再把它变回可配置的了。此时,在调用Object.defineProperty()方法修改处writable之外的性状,都会产生错误

 

那个例子制造了1个名称叫name的性质,它的值”Nicolas”是只读的.那本个性的值是不行修改的,若是尝试为它钦点新值,则在非严刻方式下,赋值操作将被忽略;在严谨形式下,赋值操作将会促成抛出错误.

 1     var person = {};
 2     Object.defineProperty(person,"name",{
 3         configurable: false,
 4         value: "Nicholas"
 5     });
 6 
 7     //抛出错误
 8     Object.defineProperty(person,"name",{
 9         configurable: true,
10         value:"Nicholas"
11     });

 

类似的条条框框也适用于不可配置的属性.

 

指标直接量是2个表明式,每一回运算都会创立并开始化2个新的目的。

var person={};
    Object.defineProperty(person,"name",{
        configurable:false,
        value:"Nicholas"
    });

    alert(person.name);//Nicholas
    delete person.name;
    alert(person.name);//Nicholas

在调用Object.defineProperty()方法时,假如不点名,configurable、enumerable和writable脾性的私下认可值都是false

(二)、通过new成立对象

把configurable设置为false,表示无法从目的中去除属性.假使对那一个性情调用delete,则在非严刻方式下什么样也不会时有爆发,而在从严形式下会变成错误.而且,一旦把质量定义为不可配置的,就不能够再把它变回可配置了.此时,再调用Object.defineProperty()方法修改除writable之外的风味,都会产生错误:

 

new运算符创设并开首化3个新指标。关键字new后紧跟着八个函数调用。那里的函数称作构造函数(constructor),构造函数用于早先化一个新创立的靶子。

var person={};
    Object.defineProperty(person,"name",{
        configurable:false,
        value:"Nicholas"
    });

    Object.defineProperty(person,"name",{//Uncaught TypeError: Cannot redefine property: name
        configurable:true,
        value:"Nicholas"
    });

2、访问器属性

如:

约等于说,能够频繁调用Object.defineProperty()方法修改同1属性,但把configurable性子设置为false之后就会有限量了.

走访器属性不包涵属性值;他们带有1对儿getter和setter函数,在读取访问器属性时,会调用setter函数,这几个函数负责再次回到有效的值,在写入访问器属性时,会调用getter函数,并传播新值,那个函数决定哪些处理数据。访问器属性有如下6个特色

 

在调用Object.defineProperty()方法时,倘若不钦点,configurable,enumerable和writable性情的默认值都以false.

[[Configurable]]:表示是还是不是通过delete输出属性从而定义属性,能或不能够修改属性的性状,或然是或不是把品质修改为访问器属性,暗中同意值为true

 

在意:IE捌是率先个落到实处Object.defineProperty()方法的浏览器版本.但是,这些本子的贯彻存在不少范围:只还好DOM对象上应用那些法子,而且只可以创设访问器属性.由于达成不根本,建议不要在IE第88中学使用Object.defineProperty()方法.

[[Enumerable]]:表示是不是通过for-in循环重回属性,默许值为true

 

二.做客器属性

[[Get]]:在读取属性时调用的函数。默许值为undefined

 

做客器属性不含有数据值:它们含有1对儿getter和setter函数(可是,那七个函数都不是须要的).在读取访问器属性时,会调用getter函数,那么些函数负责重回有效的值;在写入访问器属性时,会调用setter函数并传到新值,那几个函数负责调整如何处理数据.

[[Set]]:在写入属性时调用的函数。默许值为undefined

1

访问器属性有如下多少个特征:

 

1

[[Configurable]]:表示是不是通过delete删除属性从而再一次定义属性,能无法修改属性的表征,大概是不是把质量修改为数量属性.对于向来在对象上定义的质量,那些特点的暗中认可值为true.

做客器属性无法一向定义,必须采用Object.defineProperty()来定义。

 

[[Enumberable]]:表示是还是不是通过for-in循环重临属性.对于一贯在对象上定义的品质,这几个脾气的暗许值为true.

 1     var book = {
 2         _year: 2004,
 3         edition: 1
 4     };
 5 
 6     Object.defineProperty(book,"year",{
 7         get: function(){
 8             return this._year;
 9         },
10         set: function(newValue){
11             if(newValue > 2004){
12                 this._year = newValue;
13                 this.edition += newValue - 2004;
14             } 
15         }
16     });
17 
18     book.year = 2005;
19     console.log(book.edition); //2

 

[[Get]]:在读取属性时调用的函数.私下认可值为undefined.

 

 

[[Set]]:在写入属性时调用的函数.默认值为undefined.

 

 

访问器无法平昔定义,必须使用Object.defineProperty()来定义.

这是运用访问器的常见形式,即设置1性格质的值会导致别的质量爆发变化,year后面包车型大巴下划线是一种

 

var book={
        _year:2004,
        edition:1
    };

    Object.defineProperty(book,"year",{
        get:function(){
            return this._year;
        },
        set:function(newValue){
            if(newValue>2004){
                this._year=newValue;
                this.edition+=newValue-2004;
            }
        }
    });

    book.year=2005;
    alert(book.edition);//2

常用的暗号,用于表示只可以通过对象方法访问的习性

1

以上代码成立了一个book对象,并给它定义五个暗中同意的习性:_year和edition.

不必然非要同时钦定getter和setter。只钦赐getter意味着属性是不可能写的,只钦命setter函数的性格
也不能够读

var o = new Object();     //创建一个空对象

_year前边的下划线是壹种常用的标识,用于表示只可以通过对象方法访问的属性.而访问器属性year则带有1个getter函数和一个setter函数.getter函数再次来到_year的值,setter函数通过测算来鲜明科学的版本.这是利用访问器属性的科学普及方式,即设置一个天性的值会促成其余属性产生变化.

五个非标准化准的办法:__defineGetter__()和__defineSetter__()

 

不自然非要同时钦定getter和setter.只钦定getter意味着属性是不能够写,尝试写入属性会被忽略.在严谨情势下,尝试写入只钦赐了getter函数的个性会抛出错误.类似的,只内定setter函数的质量也不能够读,不然在非严酷情势下会重回undefined,而在从严格局下会抛出错误.

 1     var book = {
 2         _year: 2004,
 3         edition: 1
 4     };
 5 
 6     book.__defineGetter__("year",function(){
 7             return this._year;
 8         });
 9     book.__defineSetter__("yeat",function(newValue){
10                     if(newValue > 2004){
11                 this._year = newValue;
12                 this.edition += newValue - 2004;
13             } 
14     });
15 
16     book.year = 2006;
17     console.log(book.year);

 

在ECMAScript
5的这几个主意从前,要创建访问器属性,壹般都选择五个非标准化准的方法:_defineGetter_()和_defineSetter_().

 

(3)、Object.create()

在不扶助Object.defineProperty()方法的浏览器中不能够修改[[Configurable]]和[[Enumberable]].

概念八个属性

它成立1个新对象,其中第多个参数是那一个指标的原型,第三个为可选参数,用以对目的的性质进一步描述。

陆.1.二 定义多个天性


它是二个静态函数,而不是提要求某些对象调用的不二秘籍。

是因为为对象定义三特性格的恐怕非常的大,ECMAScript
5又定义了贰个Object.defineProperties()方法.利用这几个办法能够由此讲述符1回定义多少个属性.这些主意接收两个对象参数:第二个目的是要加多和修改其属性的对象,第三个指标的习性与第多少个目的中要加上或涂改的本性一一对应.

 

如:

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;
                }
            }
        }    
    });

Object.defineProperties()方法。利用那么些方法能够通过讲述符3次定义多脾个性。

 

如上代码在book对象上定义了五个数据属性(_year和edition)和3个拜访器属性(year).最后的指标与上1节定义的目的同样.唯1的差异是此处的属性都以在同方今间创造的.

 1     var book = {};
 2 
 3     Object.defineProperties(book,{
 4         _year: {
 5             value: 2004
 6         },
 7         edition: {
 8             value: 1
 9         },
10         year: {
11             get: function(){
12                 return this._year;
13             },
14             set: function(newValue){
15                 if(newValue > 2004){
16                     this._year = newValue;
17                     this.edition += newValue - 2004;
18                 }
19             }
20         }
21     });

 

6.一,三 读取属性的特色

 

 

动用ECMAScript
5的Object.getOwnPropertyDescriptor()方法,能够拿走给定属性的叙述符.这一个方法接收多个参数:属性所在的靶子和要读取其叙述符的习性名称.再次来到值是贰个对象,假设是造访器属性,那些指标的属性有configurable,enumberable,get和set;假设是多少属性,那一个指标的品质有configurable,enumberable,writable和value.

读取属性的表征

 

var book={};
    Object.defineProperties(book,{
        _year:{
            value:2004
        },
        edition:{
            value:1
        },
        year:{
            get:function(){
                return this._year;
            },
            set:function(newValue){
                if(newValue>2004){
                    this._year=newValue;
                    this.edition+=newValue-2004;
                }
            }
        }
    });
    var descriptor=Object.getOwnPropertyDescriptor(book,"_year");
    alert(descriptor.value);//2004
    alert(descriptor.configurable);//false
    alert(typeof descriptor.get);//undefined
    var descriptor=Object.getOwnPropertyDescriptor(book,"year");
    alert(descriptor.value);//undefined
    alert(descriptor.enumberable);//undefined
    alert(typeof descriptor.get);//function

2

对此数据属性_year,value等于最初的值,configurable是false,而get等于undefined.对于访问器属性year,value等于undefined,enumerable是undefined,而get是1个针对性getter函数的指针.

Object.getOwnPropertyDescriptor()方法,可以赢得给定属性的叙述符

2

在JavaScript中,能够本着别的对象–包罗DOM和BOM对象,使用Object.getOwnPropertyDescriptor()方法.

 

 

 1     Object.getOwnPropertyDescriptor()方法,可以取得给定属性的描述符
 2 
 3     var book = {};
 4 
 5     Object.defineProperties(book,{
 6         _year: {
 7             value: 2004
 8         },
 9         edition: {
10             value: 1
11         },
12         year: {
13             get: function(){
14                 return this._year;
15             },
16             set: function(newValue){
17                 if(newValue > 2004){
18                     this._year = newValue;
19                     this.edition += newValue - 2004;
20                 }
21             }
22         }
23     });
24 
25     var descriptor = Object.getOwnPropertyDescriptor(book,"_year");
26     console.log(descriptor.value); //2004
27     console.log(descriptor.configurable); //false
28     console.log(typeof descriptor.get); //"underfined"
29 
30     var descriptor = Object.getOwnPropertyDescriptor(book,"year");
31     console.log(descriptor.value); //underfined
32     console.log(descriptor.enumerable); //false
33     console.log(typeof descriptor.get); //"function"

 

 

 

 

 

1

var o = Object.create({ x: 1, y: 2});     //o继承了属性x和y

2

var o2 = Object.create(Object.prototype);    //创建一个空对象

 

 

二、属性的查询和安装

当通过[]来走访对象的属性时,属性名通过字符串来表示。

使用[]运算符访问时,字符串值是动态的,能够在运营时更动。

动用 . 运算符访问时,后接的是标志符,标记符是静态的,写死在程序中。

今非昔比的景观能够选用不相同的运算符来进行访问。

(1)继承

对品质赋值操作时首先要反省原型链,以此剖断是不是允许赋值。

即使二个目的承继自另三个对象的贰个自读属性,那么赋值操作是不容许的。

要是同意属性赋值操作,它总是在原始对象上成立属性或对已部分属性赋值,而不会去修改原型链。

 

 

 

 

6

6

 

 

 

 

 

1

//这里使用es5 的Object.create()函数来创建对象

2

var o = {r: 1};    //一个用来继承的对象

3

var c = Object.create(o);     //创建一个新对象c,c继承o对象属性r

4

c.x = 1; c.y = 2;     //c定义两个属性

5

c.r = 2;     //c覆盖继承来的属性

6

console.log(o.r);    //1 原型对象没有修改

 

 

(贰)、属性访问错误

在仓卒之际那个现象下给目的o设置属性p会失败:

  • o中的属性p是只读的:不能够给只读属性重新赋值(defineProperty()方法中有1个比不上,能够对可配备的只读属性重新赋值)。
  • o中的属性p是承继属性,且它是只读的:不能够通过同名自有品质覆盖只读的一连属性。
  • o中不存在自有属性p:o未有选用setter方法承袭属性p,并且o的可扩充性是false。若是o中不存在p,而且从不setter方法可供调用,则p一定会增添至o中。但如若o不是可扩展的,那么在o中无法定义新属性。

3、删除属性

经过delete运算符能够去除对象的性质。

delete运算符只可以删除自有质量,无法去除承接属性。(要去除承继属性必须从概念那特性子的原型对象上删除它,而且那会潜移默化到独具继续自那些原型的对象)。

delete无法去除那一个可配置性为false的属性。(就算可以去除不可扩展对象的可布置属性)

 

 

 

 

6

6

 

 

 

 

 

1

o = {x:1};

2

delete o.x;    //true

3

delete o.x;     //什么也没做(x已经不存在),返回true

4

delete o.toString;     //什么也没做(toString是继承来的) ,返回true

5

delete 1;     //无意义,返回true

6

delete Object.prototype;     //不能删除,属性是不可配置的

 

 

四、检查测试属性

(1)、in运算符

用以检查测试三个对象是否包涵有些属性,假若指标的自有总体性或一而再属性中包罗那个性子则赶回true。

如:

 

 

 

 

4

4

 

 

 

 

 

1

var o = { x:1 };

2

"x" in o;     //true "x"是o的属性

3

"y" in o;    //false    "y"不是o的属性

4

"toString" in o;     //true o继承toString属性

 

 

(2)、hasOwnProperty()方法

用来检查评定给定的名字是还是不是是对象的自有总体性,对于持续属性它将回到false。

如:

 

 

 

 

4

4

 

 

 

 

 

1

var o = { x:1 };

2

o.hasOwnProperty("x");    //true o有一个自有属性x

3

o.hasOwnProperty("y");    //false o中不存在属性y

4

o.hasOwnProperty("toString");    //false toString是继承属性

 

 

(3)、propertyIsEnumerable()方法

它用来检测是自有属性且这几个天性的可枚举性为true时它才回去true。

好几内置属性是见惯不惊的,平时由javascript代码成立的脾性都以可枚举的。如

 

 

 

 

5

5

 

 

 

 

 

1

var o = Object.create({ y: 2});

2

o.x = 1;

3

o.propertyIsEnumerable("x");    // true: o有一个可枚举的自有属性x

4

o.propertyIsEnumerable("y");    //false y是继承来的

5

Object.prototype.propertyIsEnumerable("toString");    //false 不可枚举

 

 

(四)、判定一个属性是还是不是是undefined

使用 “ !== ”,如

 

 

 

 

8

8

 

 

 

 

 

1

var o = { x:1 };

2

o.x !== undefined;     //true o中有属性x

3

o.y !== undefined;     //false o中没有属性y

4

o.toString !== undefined;     //true o继承了toString属性

5

o.z = undefined;

6

o.z !== undefined;     //false 属性存在,但值为undefined

7

delete o.z;    //删除属性

8

"z" in o;    //false,属性不存在

 

 

5、属性getter和setter

在es5中,属性值能够用1个或七个方法替代,那么些三个法子是getter和setter。由getter和setter定义的性能称做“存取器属性”。

存取器属性不有所可写性。若是属性同时负有getter和setter方法,那么它是三个读/写属性,假诺只有getter方法,那么它是二个只读属性,假若它唯有setter方法,那么它唯有一个只写属性(数据属性中有部分两样)

getter方法:无参数,再次来到值是性质存取表明式的值。

setter方法:3个参数,设置属性值,

语法:

 

 

 

 

6

6

 

 

 

 

 

1

var o = {

2

    data_prop: value,    //普通的数据属性

3

    //存取器属性

4

    get accessor_prop() { /*函数体 */ },

5

    set accessor_prop() { /*函数体 */ }

6

};

 

 

存取器属性是能够持续的,如

 

 

 

 

21

21

 

 

 

 

 

1

//笛卡尔点坐标对象

2

var p = {

3

x: 1.0,

4

y: 1.0,

5

get r() {

6

return Math.sqrt(this.x * this.x + this.y * this.y);    //this指代这个点的对象,即p

7

},

8

set r(newvalue) {

9

var oldvalue = Math.sqrt(this.x * this.x + this.y * this.y);

10

var ratio = newvalue / oldvalue;

11

this.x *= ratio;

12

this.y *= ratio;

13

},

14

get theta() {

15

return Math.atan2(this.y, this.x);

16

}

17

};

18

var q = Object.create(p);     //创建一个继承getter和setter的新对象

19

q.x = 2, q.y = 1;        //给q添加两个属性

20

console.log(q.r);     //可以使用继承的存取器属性

21

console.log(q.theta);

 

 

6、属性的性状

数据属性包涵伍个特点,分别是它的值(value)、可写性(writable)、可枚举性(enumerable)、可配置性(configurable)。存取器属性不抱有值脾性和可写性,它们的可写性是由setter方法存在与否决定的。因而存取器属性的5个特点是读取(get)、写入(set)、可枚举性和可配置性。

透过调用Object.getOwnPropertyDescriptor()能够拿走有个别对象特定属性的属性描述符(即表示6个特色)。

 

 

 

 

16

16

 

 

 

 

 

1

console.log(Object.getOwnPropertyDescriptor({

2

    x: 1

3

}, "x"));     //返回 {value:1, writable:true, enumerable:true, configurable:true}

4

5

var random = {

6

    get octet() {

7

        return Math.floor(Math.random() * 256);

8

    },

9

}

10

//查询定义的random对象的octet属性

11

console.log(Object.getOwnPropertyDescriptor(random, "octet")); 

12

//返回 {get: /*function函数*/, set:undefined, enumerable:true, configurable:true}

13

14

//对于继承属性和不存在的属性,返回undefined

15

console.log(Object.getOwnPropertyDescriptor({}, "x"));    //undefined

16

console.log(Object.getOwnPropertyDescriptor({}, "toString"));    //undefined

 

 

安装属性的表征,也许让新建属性具备某种天性,则供给调用Object.definePeoperty(),传入须求修改的靶子、要创设或涂改的性质的名称以及质量描述符对象

  

 

 

x

30

 

 

 

 

 

1

var o = {};     //创建一个空对象

2

//添加一个不可枚举的数据属性x,并赋值为1

3

Object.defineProperty(o, "x", {

4

    value: 1,

5

    writable: true,

6

    enumerable: false,

7

    configurable: true

8

});

9

console.log(o.x); //1

10

console.log(Object.keys(o)); //返回[]  keys方法,返回所有可枚举的属性 

11

//对属性x进行修改,让它变为只读

12

Object.defineProperty(o, "x", {

13

    writable: false

14

});

15

o.x = 2; //更改属性值

16

console.log(o.x);    //1 没有被更改,属性是只读

17

18

//属性是可配置的,因此可以通过这种方式对它进行修改

19

Object.defineProperty(o, "x", {

20

    value: 2

21

});

22

console.log(o.x);    // 2

23

//将x从数据属性修改为存取器属性

24

Object.defineProperty(o, "x", {

25

    get: function() {

26

        return 0;

27

    }

28

});

29

console.log(o.x);     // 0

30

console.log(Object.getOwnPropertyDescriptor(o, "x"));     //查看x的特性

 

 

万一供给同时修改或创设多个属性,并安装属性描述符,则要求使用Object.defineProperties()。参数一为该目的,参数2为二个映射表。如:

 

 

 

 

22

22

 

 

 

 

 

1

//首先创建一个空对象,然后给它添加两个数据属性和一个只读存取器属性。

2

var p = Object.defineProperties({}, {

3

    x: {

4

        value: 1,

5

        writable: true,

6

        enumerable: true,

7

        configurable: true

8

    },

9

    y: {

10

        value: 1,

11

        writable: true,

12

        enumerable: true,

13

        configurable: true

14

    },

15

    r: {

16

        get: function() {

17

            return Math.sqrt(this.x * this.x + this.y * this.y)

18

        },

19

        enumerable: true,

20

        configurable: true

21

    }

22

});

 

 

规则:

  • 设若指标是不可扩大的,则足以编写制定已有个别自有总体性,但不能够给它丰硕新属性。
  • 借使属性是不可配置的,则不能够修改它的可配置性和可枚举性。
  • 一旦存取器属性是不行配置的,则不可能改改其getter和setter方法,也不能够将它转变为数量属性。
  • 借使数量属性是不行配置的,则不能够将它调换为存取器属性。
  • 倘若数据属性是不可配置的,则无法将它的可写性从false修改为true,但能够从true修改为false。
  • 1旦数量属性是不行配置且不可写的,则不能够改改它的值。可是可配置但不足写属性的值是可以修改的(实际上是先将它标志为可写,然后修改它的值,最终调换为不可写的)。

例子:复制属性的特色

 

 

 

 

21

21

 

 

 

 

 

1

/*

2

    *给Object.prototype添加一个不可枚举的extend()方法

3

    这个方法继承自调用它的对象,将作为参数传入的对象的属性一一复制

4

    除了值之外,也复制属性的所有特性,除非在目标对象中存在同名的属性

5

    参数对象的所有自有对象(包括不可枚举的属性)也会一一复制

6

*/

7

Object.defineProperty(Object.prototype, "extend", {

8

    writable: true,

9

    enumerable: false,     //不可枚举

10

    configurable: true,

11

    value: function(o) {

12

        var names = Object.getOwnPropertyNames(o);     //得到所有的自有属性,包括不可枚举属性

13

        for (var i = 0; i < names.length; i++) {

14

            if (names[i] in this) {        //如果属性已经存在,则跳过

15

                continue;

16

            }

17

            var desc = Object.getOwnPropertyDescriptor(o, names[i]); //获取o中的属性描述符

18

            Object.defineProperty(this, names[i], desc);    //用它给当前对象(this)创建一个属性

19

        }

20

    }

21

});

 

 

7、对象的多少个属性

(一)原型属性

原型属性是在实例对象创立之初就设置好的。

透过Object.getPrototypeOf()方法能够查询某些对象的原型

如:

 

 

 

 

7

7

 

 

 

 

 

1

function People() {}     //空的构造函数

2

People.prototype = {     //设置原型属性

3

    constructor: People,

4

    name: "cart",

5

}

6

var cc = new People();    //实例化构造函数,创建一个新的对象

7

console.log(Object.getPrototypeOf(cc));

 

 

检查实验二个对象是还是不是是另3个对象的原型,用isPrototypeOf()方法

 

 

 

 

7

7

 

 

 

 

 

1

//定义一个原型对象

2

var p = {

3

    x: 1

4

};

5

var o = Object.create(p);     //使用原型对象创建一个对象

6

console.log(p.isPrototypeOf(o));     // true

7

console.log(Object.prototype.isPrototypeOf(o));     //true o继承p,p继承Object.prototype

 

 

(2)类属性

目的的类属性是叁个字符串,用以代表对象的类型消息。

经过toString()方法能够直接的询问到这几个目的的类属性。再次回到如下格式的字符串:

[
object class ]

所以,要想赢得对象的类,能够调用对象的toString()方法,然后提取已重临字符串的第拾一个到倒数第2个地点之间的字符。

 

 

 

 

13

13

 

 

 

 

 

1

// 定义一个获取对象类属性的函数

2

function classof(o) {

3

    if (o === null) {

4

        return "Null";

5

    }

6

    if (o === undefined) {

7

        return "Undefined";

8

    }

9

    return Object.prototype.toString.call(o).slice(8, -1); //间接调用toString方法返回类属性

10

}

11

classof(1);     // NUmber

12

function f() {};     //定于一个自定义构造函数

13

classof(new f());     // Object

 

 

(3)、可扩张性

  • 指标的可扩充性用以代表是或不是足以给目的增多新属性。能够通过将对象传入Object.isExtensible(),来判别该指标是不是是可扩张的。

  • 设若想将指标调换为不可扩展的,须求调用Object.preventExtensions(),将待调换的对象作为参数字传送进去。

目的一旦更改为不可扩充,就不可能再将其转移为可扩展的。给一个不行扩大的指标的原型增加属性,这些不可扩张的靶子同样会持续这个新属性。

 

 

 

9

9

 

 

 

 

 

1

var o = {

2

    x: 1,

3

    y: {

4

        z: [false, null, ""]

5

    }

6

};

7

console.log(Object.isExtensible(o));    //true

8

Object.preventExtensions(o);    //将对象转换为不可扩展

9

console.log(Object.isExtensible(o));    //false

 

 

  •  
    Object.seal(Object);它除了能够安装对象的不足扩张,还足以设置对象的自有品质都安装为不可配置的,无法去除和配置。对于它曾经有的可写属性仍旧能够安装。
  •    
    Object.isSealed(Object); 检核查象是或不是封闭。
  •    
    Object.freeze();更严格的锁定目标(冻结)。除了将对象设置为不可扩充,属性设置为不可配置,全部的自有品质设置为只读的,(尽管目的存款和储蓄器属性有setter方法,存款和储蓄器属性不受影响,照旧能够通过质量赋值给她们)。
  •    
    Object.isFrozen() 来检查实验对象是还是不是冻结。

⑧、系列化对象

目的体系化(serialization)是指将对象的动静转变为字符串,也足以将字符串还原为对象。

利用函数JSON.stringify()和JSON.parse()用来类别化和还原javascript对象。

 

 

 

 

11

 

 

 

 

 

1

// 定义一个测试对象

2

var o = {

3

    x: 1,

4

    y: {

5

        z: [false, null, ""]

6

    }

7

};

8

var s = JSON.stringify(o);

9

var p = JSON.parse(s);

10

console.log(s);    //解析为json格式字符串 {"x":1,"y":{"z":[false,null,""]}}

11

console.log(p);    //将字符串转换为javascript对象

 

 

函数、RegExp、Error对象和undefined值不能够体系化和死灰复燃。JSON.stringify()只可以种类化对象可枚举的自有质量。

 

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图
Copyright @ 2010-2019 美高梅手机版4858 版权所有