JavaScript高级程序设计学习(五)之对象
众说周知,java是面向对象的编程语言。一个类包含多个对象,例如车类,它包含宝马,奔驰,东风,本田,莲花等这样的车,而品牌和颜色或者某种标识就是它的属性。车包含很多种类,但是共性还是有的,比如共性有四个轮子,有品牌,有发动机等等。这些可以抽象为一个类,让子类继承这些共性,子类重写父类的方法,然后在此可以新增自己的属性和方法,以此标明差异活不同。
js为什么不是面向对象的编程语言呢?
用一句说明:
面向对象(Object-Oriented,OO)的语言有一个标志,那就是它们都有类的概念,而通过类可 以创建任意多个具有相同属性和方法的对象。前面提到过,ECMAScript中没有类的概念,因 此它的对象也与基于类的语言中的对象有所不同。所以js不是面向对象的语言。
ECMA-262把对象定义为:“无序属性的集合,其属性可以包含基本值、对象或者函数。”严格来讲, 这就相当于说对象是一组没有特定顺序的值。对象的每个属性或方法都有一个名字,而每个名字都映射 到一个值。正因为这样(以及其他将要讨论的原因),我们可以把 ECMAScript的对象想象成散列表:无 非就是一组名值对,其中值可以是数据或函数。
var person = new Object(); person.name = "Nicholas"; person.age = 29; person.job = "Software Engineer"; person.sayName = function(){ alert(this.name); };
上面的例子创建了一个名为 person 的对象,并为它添加了三个属性(name、age 和 job)和一个 方法(sayName())。其中,sayName()方法用于显示 this.name(将被解析为 person.name)的值。 早期的 JavaScript开发人员经常使用这个模式创建新对象。几年后,对象字面量成为创建这种对象的首选 模式。前面的例子用对象字面量语法可以写成这样:
var person = { name: "Nicholas", age: 29, job: "Software Engineer", sayName: function(){ alert(this.name); } };
(1)属性类型
ECMA-262第 5版在定义只有内部才用的特性(attribute)时,描述了属性(property)的各种特征。 ECMA-262定义这些特性是为了实现 JavaScript引擎用的,因此在 JavaScript中不能直接访问它们。为了 表示特性是内部值,该规范把它们放在了两对儿方括号中,例如[[Enumerable]]。尽管 ECMA-262 第 3版的定义有些不同,但本书只参考第 5版的描述。 ECMAScript中有两种属性:数据属性和访问器属性。
a.数据属性
数据属性包含一个数据值的位置。在这个位置可以读取和写入值。数据属性有4个描述其行为的 特性。
[[Configurable]]:表示能否通过 delete 删除属性从而重新定义属性,能否修改属性的特 性,或者能否把属性修改为访问器属性。像前面例子中那样直接在对象上定义的属性,它们的 这个特性默认值为 true。
[[Enumerable]]:表示能否通过 for-in 循环返回属性。像前面例子中那样直接在对象上定 义的属性,它们的这个特性默认值为 true。
[[Writable]]:表示能否修改属性的值。像前面例子中那样直接在对象上定义的属性,它们的 这个特性默认值为 true。
[[Value]]:包含这个属性的数据值。读取属性值的时候,从这个位置读;写入属性值的时候, 把新值保存在这个位置。这个特性的默认值为 undefined。 对于像前面例子中那样直接在对象上定义的属性,它们的[[Configurable]]、[[Enumerable]] 和[[Writable]]特性都被设置为 true,而[[Value]]特性被设置为指定的值。
var person = { name: "Nicholas" };
b.访问器属性
访问器属性不包含数据值;它们包含一对儿 getter和 setter函数(不过,这两个函数都不是必需的)。 在读取访问器属性时,会调用 getter函数,这个函数负责返回有效的值;在写入访问器属性时,会调用 setter函数并传入新值,这个函数负责决定如何处理数据。访问器属性有如下 4个特性:
[[Configurable]]:表示能否通过 delete 删除属性从而重新定义属性,能否修改属性的特 性,或者能否把属性修改为数据属性。对于直接在对象上定义的属性,这个特性的默认值为 true。
[[Enumerable]]:表示能否通过 for-in 循环返回属性。对于直接在对象上定义的属性,这 个特性的默认值为 true。
[[Get]]:在读取属性时调用的函数。默认值为 undefined。
[[Set]]:在写入属性时调用的函数。默认值为 undefined。 访问器属性不能直接定义,必须使用 Object.defineProperty()来定义。
set和get方法作为java开发者再熟悉不过了。
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意味着属性是不能写,尝试写入属性会被忽略。 在严格模式下,尝试写入只指定了 getter 函数的属性会抛出错误。类似地,只指定 setter 函数的属性也 不能读,否则在非严格模式下会返回 undefined,而在严格模式下会抛出错误。
在java中get和set是必须一同存在的,当然也可以不存在,前提是属性必须为非私有和默认,必须为公共的,即public。否则无法调用该属性。
(2)定义多个属性
由于为对象定义多个属性的可能性很大,ECMAScript 5 又定义了一个 Object.definePro- perties()方法。利用这个方法可以通过描述符一次定义多个属性。这个方法接收两个对象参数:第一 个对象是要添加和修改其属性的对象,第二个对象的属性与第一个对象中要添加或修改的属性一一对 应。
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; } } } } );
(3)读取属性特性
使用 ECMAScript 5的 Object.getOwnPropertyDescriptor()方法,可以取得给定属性的描述 符。这个方法接收两个参数:属性所在的对象和要读取其描述符的属性名称。返回值是一个对象,如果 是访问器属性,这个对象的属性有 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(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, "yea
作为java的开发者很容易理解对象。这个概念。不过如果是初学者的话对此往往头有点大。
因此记得一位朋友说过,学java的时候最好先是从前端html,css,js这样的学,因为学到js的时候存在一个对象的概念,有助于理解java的面向对象和比较。
当然,反过来java的话,也可以方便比较。
对象,这个概念,博大精深啊!
想起对象这个概念,我想起了伟大的spring,有了spring,再也不怕对象管理和操控问题。
因为spring有控制反转的概念,可以帮我们进行对象管理。但是js没有。
调侃一句,记得某个笑话讲过,程序员最怕什么?不懂这个是笑话的人肯定会讲最怕出bug。其实这个说的也是有道理的。
不过最终的答案是,程序员最怕找不到对象,作为java程序员,java称之为面向对象的编程语言,如果找不到对象,那还有什么意思呢?
玩笑一下,程序员有的时候还是得自我调侃调侃一下。有助于身心放松。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
KernelML——一种广义机器学习算法
最近,我创造了一个自定义的“粒子优化算法”,并制作了一个叫做KernelML的Python包。创造这种算法是为了给数据分析师和数据科学家提供一个针对复杂损失函数和非线性系数的广义机器学习算法。优化算法通过简单机器学习和概率模拟的组合,使用损失函数、输入和输出矩阵以及随机采样器(可选)来寻找最优参数。目前,我在研究更多功能,希望项目最终能够开源。 使用示例: 以经纬度坐标的聚类问题作为范例,K均值的聚类方法使用欧氏距离来区别观测值。但是,经纬度坐标间的欧氏距离并不能直接映射为Haversine距离。这意味着,如果将0和1之间的坐标进行归一化,则距离无法精确的在聚类模型中得以表示。最好的解决方案就是找到坐标投影,使该点质心的Haversine距离等于欧式空间中的投影距离。 以上坐标变换在聚类解决方案中的缩放和使用,将相对于中心的Havers
- 下一篇
Grid++Report报表工具C/S实战篇(五)
一、课程介绍 本次分享课程属于《C#高级编程实战技能开发宝典课程系列》中的第五部分,阿笨后续会计划将实际项目中的一些比较实用的关于C#高级编程的技巧分享出来给大家进行学习,不断的收集、整理和完善此系列课程! 本次分享课程适合人群如下: 1、想学习Grid++Report报表工具在C/S项目中的实战演练。 2、喜欢阿笨的干货分享课程的童鞋们。 3、想解决我们在实际工作中运到的“复杂多变”的标签打印痛点问题。 本次分享课涉及覆盖的知识点: 1)、Grid++Report报表工具正确的安装步骤以及科学的快速学习方法分享。 2)、掌握Grid++Report报表工具使用过程中需要注意事项。 3)、掌握Grid++Report报表工具在C/S项目中的基本运用。 4)、掌握Grid++Report报表工具如何在生产环境C/S项目中的进行发布部署。 5)、基于Grid++Report报表工具开发的两个C/S项目中的实例分享。 6)、如何灵活地采用面向对象设计解决我们项目中经常遇到复杂多变的“标签打印”需求痛点。(强烈推荐) 希望大家在选择阿笨的C#高级编程实战技能开发宝典课程系列的时候,根据自身的情...
相关文章
文章评论
共有0条评论来说两句吧...