我真的很佩服副院长~他是一个很有耐心 极其细致的人
工作态度严谨 代码简洁风格统一~再乱遭遭的代码只要经过他的手就会变的很漂亮
羡煞我也~
不说废话了 还是乖乖看书吧~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]
先了解下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().