HTML5技术

深入学习JavaScript对象 - clearbug(2)

字号+ 作者:H5之家 来源:博客园 2015-09-28 18:10 我要评论( )

概述中说过, JavaScript对象具有自有属性,也有继承属性。当查询对象obj的属性x时,首先会查找对象obj自有属性中是否有x,如果没有,就会查找对象obj的原型对象obj.prototype是否有属性x,如果没有,就会进而查找

  概述中说过,JavaScript对象具有”自有属性“,也有“继承属性”。当查询对象obj的属性x时,首先会查找对象obj自有属性中是否有x,如果没有,就会查找对象obj的原型对象obj.prototype是否有属性x,如果没有,就会进而查找对象obj.prototype的原型对象obj.prototype.prototype是否有属性x,就这样直到找到x或者查找到的原型对象是undefined的对象为止。可以看到,一个对象上面继承了很多原型对象,这些原型对象就构成了一个”链“,这也就是我们平时所说的“原型链”,这种继承也就是JavaScript中“原型式继承”(prototypal inheritance)。

  对象o查询某一属性时正如上面所说会沿着原型链一步步查找,但是其设置某一属性的值时,只会修改自有属性(如果对象没有这个属性,那就会添加这个属性并赋值),并不会修改原型链上其他对象的属性。

四.存取器属性getter和setter

  上面我们所说的都是很普通的对象属性,这种属性称做“数据属性”(data property),数据属性只有一个简单的值。然而在ECMAScript 5中,属性值可以用一个或两个方法替代,这两个方法就是getter和setter,有getter和setter定义的属性称做“存取器属性”(accessor property)。

  当程序查询存取器属性的值时,JavaScript调用getter方法(无参数)。这个方法的返回值就是属性存取表达式的值。当程序设置一个存取器属性的值时,JavaScript调用setter方法,将赋值表达式右侧的值当做参数传入setter。如果属性同时具有getter和setter方法,那么它就是一个读/写属性;如果它只有getter方法,那么它就是一个只读属性,给只读属性赋值不会报错,但是并不能成功;如果它只有setter方法,那么它是一个只写属性,读取只写属性总是返回undefined。看个实际的例子:

1 var p = { 2 x: 1.0, 3 y: 2.0, 4 get r(){ return Math.sqrt(this.x*this.x + this.y*this.y); }; 5 set r(newvalue){ 6 var oldvalue = Math.sqrt(this.x*this.x + this.y*this.y); 7 var ratio = newvalue/oldvalue; 8 this.x *= ratio; 9 this.y *= ratio; 10 }, 11 get theta(){ return Math.atan2(this.y, this.x); },
    print: function(){ console.log('x:'+this.x+', y:'+this.y); } 12 };

   正如例子所写,存取器属性定义一个或两个和属性同名的函数,这个函数定义并没有使用function关键字,而是使用get和set,也没有使用冒号将属性名和函数体分隔开。对比一下,下面的print属性是一个函数方法。注意:这里的getter和setter里this关键字的用法,JavaScript把这些函数当做对象的方法来调用,也就是说,在函数体内的this指向这个对象。下面看下实例运行结果:

     正如控制台的输出,r、theta同x,y一样只是一个值属性,print是一个方法属性。

   ECMAScript 5增加的这种存取器,虽然比普通属性更为复杂了,但是也使得操作对象属性键值对更加严谨了。

五.删除属性

  程序猿撸码一般都是实现增、删、改、查功能,前面已经说了增、改、查,下面就说说删除吧!

  delete运算符可以删除对象的属性,它的操作数应该是一个属性访问表达式。但是,delete只是断开属性和宿主对象的联系,而不会去操作属性中的属性:

1 var a = {p:{x:1}}; 2 var b = a.p; 3 delete a.p;

  执行这段代码后b.x的值依然是1,由于已删除属性的引用依然存在,所以有时这种不严谨的代码会造成内存泄露,所以在销毁对象的时候,要遍历属性中的属性,依次删除。

  delete表达式返回true的情况:

    ①删除成功或没有任何副作用(比如删除不存在的属性)时;

    ②如果delete后不是一个属性访问表达式;

1 var obj = {x: 1,get r(){return 5;},set r(newvalue){this.x = newvalue;}}; obj.x; obj.r; obj.toString; 1; //数字1不是属性访问表达式,返回true

  delete表达式返回false的情况:

    ①删除可配置性(可配置性是属性的一种特性,下面会谈到)为false的属性时;

x = 1; .x; f() {} .f; //返回false

六.属性的特性  

  上面已经说到了属性的可配置性特性,因为下面要说的检测属性和枚举属性还要用到属性的特性这些概念,所以现在就先具体说说属性的特性吧!

  除了包含名字和值之外,属性还包含一些标识它们可写、可枚举、可配置的三种特性。在ECMAScript 3中无法设置这些特性,所有通过ECMAScript 3的程序创建的属性都是可写的、可枚举的和可配置的,且无法对这些特性做修改。ECMAScript 5中提供了查询和设置这些属性特性的API。这些API对于库的开发者非常有用,因为:

    ①可以通过这些API给原型对象添加方法,并将它们设置成不可枚举的,这让它们更像内置方法;

    ②可以通过这些API给对象定义不能修改或删除的属性,借此“锁定”这个对象;

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • HTTP协议学习随笔 - 糖醋酸辣椒

    HTTP协议学习随笔 - 糖醋酸辣椒

    2017-05-01 18:03

  • 【react学习】关于react框架使用的一些细节要点的思考 - 外婆的彭湖湾

    【react学习】关于react框架使用的一些细节要点的思考 - 外婆的彭湖

    2017-04-16 18:00

  • 计算机网络——DNS协议的学习与实现 - 学数学的程序猿

    计算机网络——DNS协议的学习与实现 - 学数学的程序猿

    2017-04-16 10:00

  • ASP.NET Core MVC 源码学习:详解 Action 的激活 - Savorboard

    ASP.NET Core MVC 源码学习:详解 Action 的激活 - Savorboard

    2017-04-14 13:04

网友点评
e