JavaScript学习笔记6 面向对象之理解对象

在HTML中使用JavaScript(此段补充之前没写的内容)

<script>标签的属性

 - async 表示应该立即下载脚本,但不妨碍页面中的其他操作(异步执行),比如下载其他资源或等待加载其他脚本。只对外部脚本文件有效
 - charset 设置字符集 基本浏览器被忽略,很少人用
 - defer 表示脚本可以延迟到文档完全被解析和显示之后再执行。只对外部脚本文件有效。
 - language 已废弃
 - scr 表示包含要执行代码的外部文件
 - type language的替代属性;表示编写代码使用的脚本语言的内容类型。text/javascript和text/ecmascript都已经不被推荐使用。但是考虑到约定俗成和最大限度的浏览器兼容性,目前type的属性仍是text/javascript  不设置 type 属性 默认为text/javascript.

建议使用src 引入JS文件,好处如下:

 1. 可维护性:所有JS文件放在同一个文件夹下,可以集中精力写JS代码,不用去考虑HTML
 2. 可缓存:如果有两个页面使用同一个JS文件,那么这个文件只需要被下载一次,能够加快页面对的加载速度
 3. 适应未来,通过外部文件来包含JavaScript无须使用前面提到XHTML或注释back.HTML和XHTML包含外部文件的语法都是相同的。

面向对象的程序设计

  • 理解对象
  • 属性类型

    • 数据属性
      • Configurable
      • Enumerable
      • Writable
      • Value
    • 访问器属性
      • Configurable
      • Enumerable
      • Get
      • Set
  • 读取属性的特性Object.getOwnPropertyDescriptor()

理解对象

创建一个自定义对象的最简单方式就是创建一个Object的实例,然后再为它添加数据和方法如下:

var person=new Objcet();

person.name="Nicholas";
person.age=29;
person.job="Software Engineer";

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

早期的程序员使用这种模式创建新对象,后来用如下模式:(对象字面量)

var person={
    name:"Nicholas",
    age:29,
    job:"Software Engineer",
    sayName : function(){
        alert(this.name);
    }
};

两种方式创建的对象一样,都有相同的属性和方法。这些属性在创建时都会带有一些特征值,JavaScript通过这些特征值来定义他们的行为

属性类型

ECMA-262第五版在定义只有内部才用的特性时,描述了属性(property)的各种特征。ECMA-262定义这些特性是为了实现JavaScript引擎用的,因此在JavaScript中不能直接访问他们。为了表示特性是内部值,该规范把他们放在了两队方括号中,列入[[Enumerable]]。

ECMAScript中有两种属性:数据属性和访问器属性

数据属性(有4个描述其行为的特性)
  • [[Configurable]]: 表示能否通过delete删除属性,从而重新定义属性,能否修改属性的特性、能否把属性修改为访问器属性。 像前面例子中那样直接在对象上定义的属性,他们的这个特性默认为true。
  • [[Enumerable]]:表示能否通过 for-in循环返回属性。像前面例子中那样直接在对象上定义的属性,它们的这个特性默认值为true.( for in循环请参考 http://www.w3school.com.cn/js/js_loop_for_in.asp)
  • [[Writable]]:表示能否修改属性的值,像前面例子中那样直接在对象上定义的属性,它们的这个特性默认值为true.
  • [[Value]]:包含属性的数据值。读取属性值得时候,从这个位置读;写入属性值得时候,把新值保存在这个位置。这个特性的默认值为undefined。
    例如:
 var person={
     name:"Nicholas"
 };

name 的属性类型是 数据属性
行为特性值为
[[Configurable]] =true 可配置的
[[Enumerable]] =true 可列举的;
[[Writable]] =true 可写的
[[Value]] =”Nicholas”
如果 person.name=”123”;
则[[Value]] =”123”;
要想修改属性默认的特征,必须使Object.defineProperty()方法 ,传三个参数 1.属性所在对象,2.属性名,3.一个描述符对象,描述符对象的属性必须是:configurable、enumerable、writable和value 。设置其中的一或多个值,可以修改对应的特性值。例如:


Object.defineProperty(person,"name" ,{
    writable:false,//设置可写为false   (只读)
    value:"Nicholas"
});
alert(person.name);//Nicholas
person.name="111"; //在非严格模式下,赋值操作将被忽略;在严格模式下会抛出错误
alert(person.name);Nicholas

类似规则也适用于不可配置的属性(configurable)

var person={};
Object.defineProperty(person,"name",{
    //表示不能从对象中删除属性,如果这个属性调用delete
    //非严格模式下将被忽略
    //严格模式下抛出异常
    //一旦修改为不可配置的,就不能再变回可配置了
    //此时再调用Object.defineProperty()方法修改出了writable之外的特性,都会导致错误 抛出异常
    configurable:false,   
    value:"Nicholas"
});
alert(person.name);//Nicholas
person.name="111"; 
alert(person.name);//Nicholas


// person 为不可配置  抛出异常
Object.defineProperty(person,"name",{
    configurable:true,   
    value:"Nicholas"
});

  • 可以多次调用Object.defineProperty()方法修改同一个属性,但在把configruable属性设置为false之后就会有限制了。
  • 在调用Object.defineProperty()方法时,如果不指定configruable、enumerable和writable特性,默认值都是false. 多数情况下都没有必要利用Object.defineProperty()方法提供的这些高级功能。不过,理解这些概念对理解JavaScript对象却非常有用。
访问器属性

访问器属性不包含数据值;它们包含一对getter和setter函数(不过,这两个函数都不是必需的)。在读取访问器属性时,会调用getter函数,这个函数负责返回有效的值;在写入访问器属性时,会调用setter函数并传入新值,这个函数负责决定如何处理数据。
访问器属性有如下4个特性
- [[configurable]]:表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为数据属性。对于直接在对象上定义的属性,此特性默认值为true。
- [[Enumerable]]:表示能否通过for-in循环返回属性。对于直接在对象上定义的属性,此特性默认为true
- [[Get]]:在读取属性时调用的函数。默认值为undefined.
- [[Set]]:在写入属性时调用的函数。默认值为undefined.
访问器属性不能直接定义,必须使用Object.defineProperty()定义。请看下面的例子。

var book={
    // 一般私有变量 会加下划线
    _year:2004,
    edition:1
};


//创建一个 名为year的访问器   包含 getter  setter 函数 这是访问器属性最长用的方式
//即设置一个属性的值,会导致其他属性发生变化
Object.defineProperty(book,"year",{
    get : function(){
        return this._year;
    },

    set : function(newValue){
        if(newValue>this._year){
            this.edition+=newValue-this._year;

            this._year=newValue;

        }
    }



});
alert(book.year);//2004

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

不一定非要同时指定getter和setter

  • 只指定getter意味属性时不能写,非严格:没指定getter函数,尝试写入属性时会被忽略。严格:会抛出错误。
  • 只指定setter意味不能读,非严格返回undefined 。严格:抛出错误。

    在不支持Object.defineProperty()方法的浏览器中不能修改[[Configurable]] 和[[Enumerable]]。

    定义多个属性

    由于为对象定义多个属性的可能性很大,ECMAScript又定义了一个Objcet.defineProperties()方法。利用这个方法可以通过描述符一次定义多个属性。

var book={

};

Object.defineProperties(book,{

    _year:{
        configurable:true,
        writable:true,
        value :2004
    },
    edition:{
        configurable:true,
        writable:true,
        value:1
    },
    year:{
        get : function(){
            return this._year;
        },
        set : function(newValue){

            if(newValue>this._year){
                this.edition+=newValue-this._year;
                this._year=newValue;
            }
        }
    }
});

//这种写法只设置 _year edition   value的值  没有设置 configurable  writable enumerable,默认为

//设置后
alert(book.year);//2004
book.year=2005;
alert(book.edition);//2
book.year=2007;
alert(book.edition);//4
alert(book.year);//2007
alert(book._year);//2007


//没有设置 configurable  writable  不可配置 不可写 结果为
alert(book.year);//2004
book.year=2005;
alert(book.edition);//1
book.year=2007;
alert(book.edition);//1
alert(book.year);//2004
alert(book._year);//2004

读取属性的特性

使用ECMAScript5的Object.getOwnPropertyDescriptor()方法,可以取得给定属性的描述符。
返回值是一个对象
如果传入访问器属性 对象值有:
configurable、enumerable、get和set
如果是 数据属性 对象值有:
configurable、enumerable、writable和value

var book={};

Object.defineProperties(book,{
    _year :{
    configurable:true,
    value:2004

},
 edition :{
    value:1
 },
  year : {
    get : function(){
        return this._year;
    },
    set : function(newValue){

    }

  }

});

  var descriptor=   Object.getOwnPropertyDescriptor(book,"_year");
  alert(descriptor.value);//数据属性"_year" 的value值是初始值 2004  
  alert(descriptor.configurable);//数据属性"_year"的configurable值为注初始值true
  alert(descriptor.writable);//数据属性"_year"的writable值为默认值false

  alert(typeof descriptor.get);//数据属性"_year" 未定义get  undefined
  //year 和 _year 不是一样
  var descriptorYear= Object.getOwnPropertyDescriptor(book,"year");
 alert(descriptorYear.value);//访问器属性 "year" undefined  
 alert(descriptor.enumerable);访问器属性 "year" enumerable 默认值为  false
 alert(typeof descriptorYear.get)//访问器属性 "year" get 是一个指向getter函数的指针
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值