《JS权威指南学习总结--6.2属性的查询和设置》

内容要点:

.数组元素通过字符串索引而不是数字索引,这种数组就是我们所说的关联数组,也称散列、映射或字典。

二.继承

    1.JS对象具有"自有属性",也有一些属性是从原型对象继承而来的。

    2.假设要查询对象o的属性x,如果o中不存在x,那么将会继承在o的原型对象中查询属性x。如果原型对象中也没有X,但这个原型对象也有原型,那么继续在这个原型对象的原型上执行查询,直到找到X或者查找到一个原型是null的对象为止。可以看到,对象的原型属性构成了一个"链",通过这个"链"可以实现属性的继承。

    例如:

        var o={}  //o从 Object.prototype 继承对象的方法

       o.x=1;      //给o定义一个属性x

       var p=inherit(o); //P继承o和Object.prototype

       p.y=2;  //给P定义一个属性y

       var q=inherit(p); //q继承p、o和Object.prototype

       q.z=3;   //给q定义一个属性z

       var s=q.toString();   //toString继承自Object.prototype

       q.x+q.y      // => 3 : x和y分别继承自o和p

       现在假设给对象o的属性x赋值,如果o中已经有属性x(这个属性不是继承来的),那么这个赋值操作只改变这个已有属性的值。

       如果o中不存在属性x,那么赋值操作给o添加一个新属性x。

       如果之前o继承自属性x,那么这个继承的属性就被新创建的同名属性覆盖了。

       属性赋值操作首先检查原型链,以此判断是否允许赋值操作。例如,如果o继承自一个只读属性x,那么赋值操作是不允许的。

       如果允许属性赋值操作,它也总是在原始对象上创建属性或对已有的属性赋值。而不会去修改原型链。

       在JS中,只有在查询属性时才会体会到继承的存在,而设置属性则和继承无关。这是JS的一个重要特征,该特征让程序员可以有选择地覆盖继承的属性。

      属性赋值要么失败、要么创建一个属性,要么在原始对象中设置属性,但是有一个例外:

       如果o继承自属性x,而这个属性是一个具有setter方法的accessor属性,那么这时将调用setter方法而不是给o创建一个属性x。

      需要注意的是:

      setter方法是由对象o调用的,而不是定义这个属性的原型对象调用的。因此如果setter方法定义任意属性,这个操作只是针对o本身,并不会修改原型链。

三.属性访问错误

       1.查询一个不存在的属性并不会报错,如果在对象o自身的属性或继承的属性中均未找到属性,属性访问表达式o.x返回undefined.

       2.但是,如果对象不存在,那么试图查询这个不存在的对象的属性就会报错。null和undefined值都没有属性,因此查询这些值得属性就会报错。

           例如:

           //抛出一个类型错误异常,undefined没有length属性

           var len = book.subtitle.length;

       3.两种避免出错的方法:

           1)一种冗余但是很易懂的方法

             var len = undefined;

             if(book){

                  if(book.subtitle) len = book.subtitle.length;

                 }          

            2)一种更简练的常用方法,获取subtitle的length属性或undefined

            var len = book && book.subtitle && book.subtitle.length;

        4.给对象o设置属性p会失败的场景

           1)o的属性p是只读的,不能给只读属性重新赋值(defineProperty()方法中有一个例外,可以对可配置的只读属性重新赋值)   

           2)o中的属性p是继承属性,且它是只读的:不能通过同名自有属性覆盖只读的继承属性

           3)o中不存在自有属性p:o没有使用setter方法继承属性P,并且o的可扩展性是false。如果o中不存在p,而且没有setter方法可供调用,则p一定会添加至o中。但如果o不是可扩展的,那么在o中不能定义新属性。

 

原文地址:https://www.cnblogs.com/hanxuming/p/5791063.html