什么是面向对象的javaScript(一)——理解面向对象

前言

 面向对象(OO)的语言有一个标志,那就是他们都有的概念,而通过类可以创建任意多个具有相同属性和方法的对象。然而,ECMAScript中没有类的概念,因此它的对象也与基于类的语言中的对象有所不同。
 ECMAScript把对象定义为:

无序属性的集合,其属性可以包含基本值、对象、函数。

 每个对象都是基于一个引用类型创建的,这个引用类型可以是原生类型,也可以是开发人员自定义的类型。

理解对象

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

    var person  = new Object();
    person.name = "sheldon";
    person.age = 15;

    person.sayHello = function(){
        console.log(this.name)
    }

 值得关注的是:早期JS开发人员经常使用这种模式创建对象。几年后,对象字面量成为创建对象的首选模式

    var person = {
        name: "sheldon",
        age:15,
        sayHello:function(){
            console.log(this.name);
        }
    }

 这个例子的person对象与前面例子的person对象是一样的,有相同的属性和方法。

一、属性类型

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

1、数据属性

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

  • [[Configurable]]:表示能否通过delete删除属性,能否修改属性的特性。默认值是true。
  • [[Enumerable]]:表示能否通过for-in循环返回属性。默认值是true。
  • [[Writable]]:表示能否修改属性的值。默认值是true。
  • [[Value]]:这个属性的数据值。默认值是undefined

 对于像前面例子中那样直接在对象上定义的属性,他们的[[Configurable]]、[[Enumerable]]、[[Writable]]特性都默认是true,而[[Value]]特性被设置为指定的值“sheldon”

 要修改属性默认的特性,必须使用ECMAScript5的Object.defineProperty()方法,使用方式如下。

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

    alert(person.name); // sheldon
    person.name = "dog";
    alert(person.name); // sheldon

 上例属性的值“sheldon”是只读的了,严格模式下赋值会报异常,普通模式将忽视赋值操作。

 另外,可以多次调用Object.defineProperty()方法修改同一属性,但是configurable的特性一旦设置为false之后,就不行了。而且一旦调用了Object.defineProperty()方法,[[Configurable]]、[[Enumerable]]、[[Writable]]特性就都默认是false了。Object.defineProperty()方法多数情况下用不上,但是理解这些概念对理解JavaScript对象非常有用。

IE8是第一个实现Object.defineProperty()方法的浏览器版本,然而实现存在诸多限制。建议不要在IE8中使用该方法

2、访问器属性

 访问器属性不包含数据值,而是包含一对儿getter和setter函数。它还有4个特性
- [[Configurable]]:表示能否通过delete删除属性,能否修改属性的特性,能否把属性修改为数据属性。默认值是true。
- [[Enumerable]]:表示能否通过for-in循环返回属性。默认值是true。
- [[Get]]:在读取属性时调用的函数。默认值是undefined。
- [[Set]]:在写入属性时调用的函数。默认值是undefined。

 访问器属性不能直接定义,必须使用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;
            }
        }
    });

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

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

 不一定非要同时指定getter和setter。只指定getter意味着属性不能写,严格模式报错,非严格模式忽略。

 支持ECMAScrpit5的这个方法的浏览器有IE9+(IE8只是部分实现)和其他正常浏览器。

二、定义多个属性

 由于为对象定义多个属性的可能性很大,E5又定义了一个Object.defineProperties()方法,例如:

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

 支持该方法的的浏览器 IE9+和其他。

三、读取属性的特性

 E5的Object.getOwnPropertyDescriptor()方法,可以取得给定属性的描述符。该方法有两个参数:属性所属对象,要读取描述符的属性名称。返回一个对象,如果是访问器属性,该对象有属性configurable、enumerable、get、set;如果是数据属性,该对象有属性configurable、enumerable、writable、value。
 举例就略了,读者自己尝试。Js中针对任何对象都可以使用此方法,包括BOM、DOM对象。支持浏览器IE9+和其他。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值