《javascript权威指南》读书笔记 -part2

我真的很佩服副院长~他是一个很有耐心 极其细致的人

工作态度严谨  代码简洁风格统一~再乱遭遭的代码只要经过他的手就会变的很漂亮

羡煞我也~

不说废话了  还是乖乖看书吧~maybe可能也许的某一天 我也可以。。。咕~~(╯﹏╰)b还是别做白日梦了 

 --------------part2--------------------------------------------------------------------------------------------------------

注释:ECMA5-ECMAScript5
在开始之前,先讲一下关于变量的知识:

好的习惯1:把所有的变量声明放置在函数的开头是一个好的编程习惯

还有一个很重要的概念~不可变的原始值和可变的对象引用(基本类型和引用类型

javascript中的原始值:undefined null boolean  string number   原始值是不可修改的。只有他们的值相等时他们才会相等。

引用类型:对象(包括数组和函数)  他们的值是可以修改的。对象的比较均是引用的比较,当且仅当他们引用同一个基对象时,他们才相等。

这就是为什么在工作中碰到一个问题~就是我明明没有对一个数组进行操作,为什么最后它的值却改变了

记住这一句话:变量保存了基本类型的实际值,而对于引用类型只保存对它的引用值。

eg:基本类型(数值  布尔值,null和undefined)
        var a=1;
        var b=a;
        var a = 3.14;
        alert(b)                    b = 1

        引用类型(对象,数组和函数)
        var  a =[1,2,3]
        var b =a;
        a[0] = 99;
         alert(b)                   b = [99,2,3]
View Code

 

先了解下typeof运算符:

   x                                        typeof x
undefined                                 "undefined"
null                                      "object"
true/false                                "boolean"
任意数字或NaN                              "number"
任意字符串                                 "string"
任意函数                                   "function"
任意内置对象(非函数)                        "object"

 

 对象

  除了字符串、数字、true、false、null和undefined之外,javascript中的值都是对象,尽管,最常见的用法是创建,设置,查找, 删除,检测和枚举。

  1:对象的创建

    可以通过对象直接量,关键字new和ECMA5中的object.creat()创建对象。

    我想前面2个大家都很熟悉,对于第3个的方式首先解释下原型。这也是我很薄弱但是确又是很重要的知识点(\(^o^)/~我要开始啰嗦了哈)。

    每个Javascript对象(null除外)都和一个对象相关联。“另一个”对象就是我们熟知的原型,每一个对象都从原型继承属性。

    现在我们来分析下~

    对象直接量创建对象都具有同一个原型-object.prototype

    通过关键字new和构造函数调用创建的对象的原型就是构造函数的prototype属性的值。

    没有原型的对象为数不多,object.prototype就是其中之一。他不继承任何属性。其他的对象的原型都是普通对象,普通对象都具有原型。所有的内置构造函数(以及大部分自定义的构造函数)都具有一个继承自object.prototype的原型。

    eg,Date.prototype的属性继承自object.prototype。这一系列链接的原型对象就是所谓的“原型链”

    object.creat({x:1;y:2})它创建了一个对象,第一个参数是这个对象的原型。

    object.creat({object.prototype});      //他和{}和new object()一样

    object.creat()他实现了“可以使任意对象可继承”,这是一个强大的特性。此方法是ECMA5才有,那ECMA3如何去实现呢?  

eg:通过原型继承创建一个新的对象
function inherit(p){
  if(p == null)   throw TypeError();
  if(object.create)
      return object.creat(p);
  var t = typeof p;
  if(p!=="object" && p!== "function")
    throw TypeError()
 function f(){}
 f.prototype = p;
 return new f(); //返回一个新的对象 它是原型是p
}
inherit()函数的其中一个用途就是防止库函数无意间(非恶意的)修改那些不受你控制的对象
var o={x:"donit change this value"};
library_function(inherit(0));

   2:对象的查询及设置

    对像的查询还有设置可以用a.name 或者a[name].

    注意只有在查询属性时才会体会到继承的存在而设置属性则和继承无关。

    属性访问错误:当查询对象一个不存在的属性时不会报错,o.x返回undefined;但是查询不存在对象的属性时就会报错,o.x.length(null,undefined没有属性)

    可以用更简练的方法  var len = book&&book.x&&book.x.length;

  3:删除属性

     delete运算符可以只能删除对象可枚举的自有属性。

    注意delete只是断开属性和宿主对象的联系,而不会去操作属性中的属性。

    eg:a={b:{c:1}};var t = a.b;delete a.b;consolse.log({"x":t.c}) //{x:1}

    由于已经删除的属性的引用依然存在,所以t.c的值还是1,所以在销毁对象的时候,要遍历属性中的属性,依次删除。否则会造成内存泄漏。

  4:检测属性

    in:"x" in o; 检测自有属性和继承属性

    hasOwnProperty:o.hasOwnProperty("x")  检测自有属性

    propertyIsEnumberable():o.propertyIsEnumberable("x")  他是hasOwnProperty的增强版,检测可枚举的自有属性时返回true。

                  某些内置属性是不可枚举的,通常由javascript代码创建的属性都是可枚举的,除非在ECMA5中使用一个特殊的方法来改变属性的可枚举性。

    还有一种更简单的 o.x!==undefined;if(o.x) o.x *=2;

  5:枚举属性

    for/in:遍历对象中可枚举的自有属性和继承属性。对象继承的内置对象是不可枚举的。

    要获取一个对象的自有属性经常这个样子

    for(prop in p){

      if(p.hasOwnProperty(prop)){

        .....

      }

    }

  6:属性setter和getter

    对象属性是由名字,值和一组特性(attribute)构成的。在ECMA5中,属性值可以用一个或两个方法替代,就是getter和setter。

    由getter和setter定义的属性称做“存取器属性”,它不同于”数据属性“,数据属性只有一个简单的值。

    当程序查询存取器属性时,调用getter方法。设置一个存取器属性的值时,调用setter方法。

    和数据属性不同,存取器属性不具有可写性。如果属性同时具有getter和setter,那么他是一个读/写属性。如果他只有getter方法,那么它是一个只读属性。如果它只有setter方法,那么它是一个只写属性,读取只写属性总是返回Unedfined.

    和数据属性相同的是存取器属性时可以继承的。

    eg:var o = {

        x:value,

        get access(){/*函数体*/},

        set access(){/*函数体*/}      

      };

  7:属性的特性

    所有通过ECMA3的程序创建的属性都是可写的,可枚举的和可配置的,且无法对这些特性做修改的。

    但是ECMA5是可以查询和设置这些属性特性的API,这些API对于库的开发者来说是非常重要的:

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

      *   可以通过这些API给对象定义不能修改或删除的属性,借此"锁定"这个对象。

    属性包含一个名字和4个特性。数据属性的4个特性是值(value)、可写性(writable)、可枚举性(enumberable)和可配置性(configurable)。

    存取器属性的4个特性是读取(get)、写入(set)、可枚举性和可配置性。

    为了实现属性特性的查询和设置操作,ECMA5定义了一个“属性描述符”的对象

    object.getOwnPropertyDescriptor({x:1},x):获取某个对象特定属性的属性描述符,稚嫩而过得到自有属性的描述符。要想获得继承属性的特性,需要遍历原型链(object.getPrototypeOf())

    var o ={};     

    object.defineProperty(o,"x",{value:1,writable:true,enumerable:false,configurable:true});o.x;//1  object.keys(o);//[]

    这个方法要么修改已有属性要么新建自有属性,但不能修改继承属性。

    object.defineProperties():同时修改或创建多个属性

    这个我就不在深入讨论了~细节问题请看Page136

  7:对象的三个属性

    每个对象都有与之相关联的原型(prototype),类(class)和可扩展性(extensible)。这些属性有什么作用呢,以及如何去查询和设置他们呢?

    原型属性:在实例对象创建之初就是设置好的~这个我就不继续多说了。

         在ECMA5中,Object.getPrototypeOf()可以查询他的原型链,ECMA3中灭有等价的函数,可以用o.constructor.prototype来检测一个对象的原型,这种方式并不可靠,请参考后面的内容“类和模块”的讲解。

          isPrototype():检测一个对象是否是另一个对象的原型(或处于原型链中)

          instanceof :判断一个对象是否是一个类的实例。

                var d= new Date();

                d.instanceof Date; //true

                d.instanceof Object; //true 

    类属性:对象的类属性是一个字符串,用以表示对象的类型信息。Page140

    可扩展性:对象的可扩展性用以表示是否可以给对像添加新属性。对象的可扩展性通常和属性的可配置行与可写性配合使用  

  8:序列化对象

    对象序列化是指将对象的状态转化为字符串,也可将字符串转化成对象。只能序列化对象可枚举的自有属性。对于一个不能序列化的属性俩说,在序列化的输出字符串中会将这个属性省略掉。

    ECMA5中提供了JSON.stringify()和JSON.parse()用来序列化和还原

    ECMA3中可以通过引入json2.js模块来使用ECMAScript5中的这些函数

  9:toString()方法

    默认的toString方法的返回值带有的信息量很少,因此很多类都带有自定义的toString().eg:Array.toString(),Date.toString()以及Function.toString();

  10:valueOf()

    跟toString方法类似,转化为数字的时候用这个方法,返回值带有的信息量很少,因此很多类都带有自定义的valueOf().

 

 

    

  

 

posted @ 2014-02-19 14:56  ppgirl  阅读(1641)  评论(15编辑  收藏  举报