zoukankan      html  css  js  c++  java
  • 对象属性和方法

    创建对象

    var a1 = new Object();
    a1.name = "a1";
    a1.age = 20;
    a1.job = 'IT';
    a1.sayName = function(){
        console.log(this.name);
    };
    
    var a2 = {
       name:'a2',
       age:20,
       job:'IT',
       sayName:function(){
           console.log(this.name);
       }
    };

    数据属性

    数据属性包含一个数据值的位置,在这个位置可以读取和写入值,数据属性有四个描述其行为的特性。

    • Configurable:表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性,像上面例子中那样直接在对象上定义的属性,它们的这个特性默认值为true。
    • Enumerable:表示能否通过for-in循环 返回属性,像上面例子中那样直接在对象上定义的属性,它们的这个特性默认值为true。
    • Writable:表示能否修改属性的值,像上面例子中那样直接在对象上定义的属性,它们的这个特性默认值为true。
    • Value:包含这个属性的数据值,读取属性值的时候,从这个位置读;写入属性值的时候,把新值保存在这个位置,这个特性的默认值为undefined。

    在上面的例子中,都含有一个名为age的属性,并为它指定的值是20,也就是说[[Value]]特性被设置为20,而对这个值的任何修改都将反映在这个位置,要修改属性默认的特性,必须使用Object。defineProperty()方法,这个方法接收三个参数:属性所在的对象、属性的名字和一个描述符(descriptor)对象。其中,描述符对象的属性必须是:configurable,enumerable,writable和value。设置其中的一个或多个值,可以修改对应的特性值。

    var b = {};
    Object.defineProperty(b,'name',{
        writable:false,
        value:'Nicholas'
    });
    console.log(b.name);   //Nicholas
    b.name = "Greg";
    console.log(b.name);   //Nicholas

    上面的例子中创建了一个name属性,他的属性值“Nicholas”是只读的,这个属性的值是不可修改的,如果尝试修改,在非严格模式下,赋值操作将被忽略,在严格模式下,赋值操作会导致抛出错误。类似的规则也适用于不可配置的属性。

    var c = {};
    Object.defineProperty(c,'name',{
        configurable:false,
        value:'Nicholas'
    });
    console.log(c.name);   //Nicholas
    delete c.name;
    console.log(c.name);   //Nicholas

    把configurable设置为false,表示不能从对象中删除该属性,如果这个属性调用delete,在非严格模式下什么也不会发生,而在严格模式下会导致错误。而且,一旦把属性定义为不可配置的,就不能再把它变回可配置了。此时,再调用Object.defineProperty()方法修改除writable之外的特性,都会导致错误。

    var d = {};
        Object.defineProperty(d,'name',{
        configurable:false,
        value:'Nicholas'
    });
    Object.defineProperty(d,'name',{  //Uncaught TypeError: Cannot redefine property: name
        configurable:true,
        value:'Nicholas'
    });

    也就是说,可以多次调用Object.defineProperty()方法修改同一个属性,但在把configurable特性设置为false之后就会有限制了。
     在调用Object.defineProperty()方法时,如果不指定,configurable,enumerable和writable特性的默认值都是false。

    访问器属性

    访问器属性不包含数据值,由一对getter和setter函数(均非必须)构成,在读取访问器属性时,会调用getter函数,这个函数负责返回有效的值;在写入访问器属性时,会调用setter函数并传入新值,这个函数负责决定如何处理数据。访问器属性有如下4个特性:

    • configurable:表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为数据属性,对于直接在对象上定义的属性,这个特性的默认值为true。
    • enumerable:表示能否通过for-in循环返回属性。对于直接在对象上定义的属性,这个特性的默认值为true。
    • get:在读取属性时调用的函数,默认值为undefined。
    • set:在写入属性时调用的函数,默认值为undefined。

    访问器属性不能直接定义,必须使用Object.defineProperty()来定义。

    var e = {
        _year:2016,
        edition:1
    };
    Object.defineProperty(e,"year",{
        get:function(){
          return this._year;
        },
        set:function(newValue){
            if(newValue > 2016){
                this._year = newValue;
                this.edition += newValue - 2016;
            }
         }
    });
    c.year = 2018;
    console.log(c.edition);  //3

    上面的例子中创建了一个对象,并给它定义了两个默认的属性:_year和edition。_year前面的下划线是一个记号,用于表示只能通过对象方法访问的属性,而访问器属性year则包含一个getter函数和一个setter函数。getter函数返回_year的值,setter函数通过计算来确定正确的版本,因此把year属性修改为2018会导致_year变成2018,而edition变为3,这是使用访问器属性的常见方式,即设置一个属性的值会导致其他属性发生变化。

    不一定非要同时指定getter和setter,只指定getter以为着属性是不能写,尝试写入属性会被忽略。在严格模式下,尝试写入只指定了getter函数的属性会抛出错误。类似低,没有指定setter函数的属性也不能读,否则在非严格模式下会返回undefined,而在严格模式下会抛出错误。

    toString

    toString() 表示的含义是把这个对象表示成字符串形式, 并且返回这个字符串形式. 首先,在Object.prototype中它对toString()方法的默认实现是"[object Object]"

      

    当我们在自己的对象或者原型上对toString()进行重写覆盖后,在访问这个对象的toString()方法时,就会沿着原型链上查找,刚好在自身对象上就找到了toString(),这是就不用再去找原型链上的顶端Object.prototype的默认的toString()了。

      

    继续看方法重写:

       

    首先是第一个打印,输出的是标准时间,也就是说,Date这个构造函数的原型其实是有toString()方法的,也就是js引擎已经在Date原型对象中重写了toString()方法,这样,就不会再继续到Object.prototype里面去寻找了。第二个打印中就能看到构造函数的原型中的toString()方法。

    从第三个和第四个打印中可以知道,js引擎在Number对象上重写了toString()方法,用于将数字转为字符串。

    valueOf()

    valueOf() 返回这个对象表示的基本类型的值!在Object.prototype.valueOf 中找到, 默认返回的是this。当需要在对象上重写valueOf()时,应该是返回一个基本数据类型的值。 先看一个默认返回的值的情况。(也就是说它是去这个对象的原型链的顶端Object.prototype.valueOf 找的valueOf方法 )
      

    在上面例子中,p1.valueOf是在Object.prototype.valueOf找到的,返回值默认this。此时this就是p1的这个对象。故结果返回true。

    valueOf()也能进行重写

        

    前面三个都是重写了valueOf()的,而第四个的打印就说明这个时候正则对象上没有valueOf,是在Object.prototype.valueOf找的,返回this,this指的就是regExp正则对象。

  • 相关阅读:
    GridView 配合模板实现 合并单元格(多列)
    Parse和Convert的区别
    'EntityValidationErrors' property for more details
    This 在 C# 中的含义
    C# 之 深入理解using
    尝试从数据库进行更新时,遇到..
    处理远程桌面不能复制粘贴解决办法
    Can't load AMD 64-bit .dll on a IA 32-bit platform错误
    MyBatis笔试题
    MyBatis延迟加载和缓存
  • 原文地址:https://www.cnblogs.com/yuyujuan/p/9169059.html
Copyright © 2011-2022 走看看