javascript高级程序设计读书笔记2
<!DOCTYPE HTML>//这个网页的文档类型,这个是html5的写法
Bootstrap使用的某些HTML元素和CSS属性需要文档类型为HTML5 doctype。因此这一文档类型必须出现在项目的每个页面的开始部分
<html lang="en">//这里的lang="en"可以删除,如果不删除的,用谷歌之类打开,它会认为是英文的,会自动给翻译(如果设置了自动翻译的话)
有两个版本的 jQuery 可供下载:
Production version - 用于实际的网站中,已被精简和压缩。
Development version - 用于测试和开发(未压缩,是可读的代码)
这两个版本都可以从 jQuery.com 下载。
提示:您可以把下载文件放到与页面相同的目录中,这样更方便使用。
如果您不希望下载并存放 jQuery,那么也可以通过 CDN(内容分发网络) 引用它。
谷歌和微软的服务器都存有 jQuery 。
如需从谷歌或微软引用 jQuery,请使用以下代码之一:
Google CDN:
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js">
</script>
</head>
提示:通过 Google CDN 来获得最新可用的版本:
如果您观察上什么的 Google URL - 在 URL 中规定了 jQuery 版本 (1.8.0)。如果您希望使用最新版本的 jQuery,也可以从版本字符串的末尾(比如本例 1.8)删除一个数字,谷歌会返回 1.8 系列中最新的可用版本(1.8.0、1.8.1 等等),或者也可以只剩第一个数字,那么谷歌会返回 1 系列中最新的可用版本(从 1.1.0 到 1.9.9)。
Microsoft CDN:
<head>
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.8.0.js">
</script>
</head>
提示:使用谷歌或微软的 jQuery,有一个很大的优势:
许多用户在访问其他站点时,已经从谷歌或微软加载过 jQuery。所有结果是,当他们访问您的站点时,会从缓存中加载 jQuery,这样可以减少加载时间。同时,大多数 CDN 都可以确保当用户向其请求文件时,会从离用户最近的服务器上返回响应,这样也可以提高加载速度。
基本类型和引用类型:
1 只能给引用类型动态的添加属性
2 var object2 = object1(var object1 = new Object())时,只是创建了一个新指针指向原来存在堆内存中的对象,该对象变化时,两个指针的引用的值都将变化(引用传递)。基本类型采用复制(值传递)数据存在栈中
3 传递参数的区别:在函数内部重写引用类型的参数之前,即使改变了参数的值,引用仍有效,而重写的只是一个局部对象,这个局部对象会在函数执行完之后立即销毁
检查基本类型时操作符typeOf()很有用(返回 类型的字符串),但检查引用类型时需要instanceOf(否则只返回object)
变量的执行环境和作用域链,延长作用域链的两种方式:with和try catch中的catch,里面的属性自动继承括号里的变量
javascript没有块级作用域,函数内没有用var声明的变量默认为全局变量,执行环境为全局环境
查询标识符一级一级向上查询,如果在当前函数环境中找到了标识符则放弃向上查询
内存回收机制
object对象是引用类型的实例:
创建object实例的两种方法:new和对象字面量(看起来更加简洁,大量传参时也亲睐)
两种访问对象属性的方法:通过变量访问属性(方括号)和点(更推崇)
array:
1 创建array的实例也有两种方法
2 array的属性length不是只读的,可以修改,改小可删除多余数据,改大会出现undefined数据
3 检测是否为数据,一般情况下instanceOf就够了,但如果网页用到多个框架的话,则可能出现array重定义,需要用Array.isArray()来检测
4 转换方法:toString(对每个元素调用toString方法),toLocaleString(对每个元素调用toLocaleString方法), valueOf
5 join() 方法用于把数组中的所有元素放入一个字符串。元素是通过指定的分隔符进行分隔的。
6 提供一种类似栈的操作方法操作数组(返回值为数组的长度,下同):pop和push,栈顶为数组末尾
7 提供一种队列的方法操作数组:push和shift(取出头部的元素) pop和unshift可以从反方向模拟队列
8 重排序的方法:reverse和sort,sort默认按升序排,调用每个元素的toString方法然后按字符顺序排序,这种显然不是我们的目的,则可以将一个比较函数作为它的参数,返回值为排序后的数组
9 操作方法:concat基于当前数组的所有项创建一个新数组, slice基于当前数组中的一项或多项创建新的数组(用法很多,详见书)
10 indexOf, lastIndexOf从后往前找,未找到返回-1,第二个参数表示查找起点
11 迭代方法:every, filter, forEach, some, map
12 缩小方法:不知道什么鬼
date:
Date.parse()和Date.UTC(),前者将字符串转化为日期,同样有toString方法,toLocaleString,valueOf返回毫秒数,便于比较
function:
函数名本来就是变量,所以函数可以当做值来使用(可以把函数当做一个参数来传递,或者返回一个函数)
函数内部的属性:arguments,是参数对象数组,它的属性callee为一个指针,指向拥有这个数组的函数
函数对象的属性:length参数的个数,prototype,该属性无法枚举出来
函数的方法apply和call,将一个对象的方法给另一个对象使用
bind()
布尔型和数字型和字符串型
重写了toString方法,toLocaleString, valueOf,基本类型的Boolean和引用类型的Boolean型差别很大,最好不要用引用类型的Boolean
number也一样重写了三个方法,第一个返回值的字符串,第三个返回基本类型的值,第一个还可以设定参数控制转成字符串的进制
toFixed()按照指定的小数位格式返回字符串形式
toExponential()返回指数形式的字符串,同样可以指定小数位
toProcession()返回最合适的格式,也可以指定小数位
String类型的字符方法:charAt()charCodeAt()
slice(),substring(), substr()的异同,参数为负的情况
trim()返回字符串副本,并去掉前置和后置空格
toLocaleUpperCase(), toUpperCase(), toLocaleLowerCase(), toLowerCase()
字符串的模式匹配函数match(),与正则式的exec()类似,参数为正则式对象或正则表达式
另一个查找模式的方法search(),唯一的参数与match相同,返回第一次找到匹配的字符索引
为了简化替换子字符串的操作,方法replace()应运而生
split();
localeCompare();
fromCharCode();
内置对象:程序员不必显式的实例化对象,因为在程序进行之前已经被实例化了
Global:所有在全局域内的方法和属性,不属于其他对象的,都是Global对象的属性和方法
encodeURIComponent()和encodeURI(),对通用资源标识符进行编码,后者只对空格编码,前者则对任何非标准字符编码,所以一般对整个URI使用encodeURIne而对URI后面的字符串使用encodeURIComponent,在实际使用中后者用的更多,因为实际中常常需要查询字符串参数而不是URI本身
与上面相反的方法decodeURI和decodeURIComponent,前者只能对对应函数编码的部分进行转码
eval()能够解释代码字符串,并将解释的代码插入原执行空间,虽然功能很强大,但是在严格模式下有问题,涉及用户输入的部分谨慎,存在恶意用户代码注入的问题
window除了扮演javascript中的global对象以外,还扮演了很多其他角色
math
对象的常用属性:Math.E, Math.PI...
min()和max()方法
apply()
舍入方法:ceil(), floor(), round()
random()
在读取模式下访问基本类型时,会常见对应的基本包装类型的一个对象,从而方便数据操作,但操作基本类型的语句一经执行完毕,就会立即销毁新创建的包装对象。
数据属性和访问器属性
Configurabale,Enumerable,Writable,Value
Configurabale,Enumerable,get,set使用访问器属性的常用方法,即设置一个属性的值会导致其他属性发生变化,浏览器兼容问题,老版非标准实现
difinePropertities()一次定义多个属性
创建对象可以采用工厂模式,将创建代码抽象成函数,避免代码冗余,问题是无法知道对象的类型
采用构造函数模式,构造函数第一个字母大写(借鉴其他OO语言),采用new操作符,这样不同的实例都有一个constructor属性为构造函数名,但是检测对象类型还是用instanceOf比较靠谱,当然构造函数模式并不是没有缺点,所以产生了原型模式:所有实例共享一组属性和方法,将属性和方法定义为构造函数原型的属性和方法,默认情况下所有的原型对象都含有一个属性constructor指向拥有该prototype的构造函数,所有实例内部又有一个原型属性指向函数原型,而不是构造函数,虽然在所有实现中都无法访问到prototype,但是可以通过函数isPrototypeOf()来判断原型是不是实例的原型,getPrototypeof(),获取原型对象,取实例属性时先找到实例有没有这个属性值,找不到在向上看看它的原型的属性值,实例自己的属性值可以把原型的属性值屏蔽掉,用函数hasOwnProperty()可以检测属性是实例的还是原型的
in操作符,能访问到该对象就返回true
hasPrototypePropertity(),如果实例中重写了属性值,那么返回false,因为实例不再用原型中的该属性值
for in返回所有可通过对象访问的,可枚举的属性,包括实例属性,本身规定开发人员设置的属性都是可枚举的(在IE8及以前例外)
早期的IEbug为使用for in会屏蔽所有默认不可枚举的属性,包括hasOwnProperty(),toString()等等,ECMA5script也将prototype和constructor设为不可枚举属性,但在不同的浏览器中实现不同
取得实例对象的所有可枚举的实例属性名的方法keys(),该方法返回字符串数组
得到所有实例属性名的方法getOwnPropertyNames,不管可不可枚举
用对象字面量写 原型属性来减少代码量,不过属性constructor就会指向object,如果constructor属性很重要,可显式的将该变量设置回去,不过这样它的访问属性就会被改为可枚举的了(默认是不可枚举的),还有新的方法,详见书
重写原型对象切断了现有原型与重写之前创建的实例的联系,以前的实例的指针依然指向在原型重写之前的原型对象
原生对象也有原型,也可以通过重写原型方法修改特性
不过原型方法也有缺点:很明显,原型的所有实例共享属性就是最大的问题,对一个实例修改它的原型属性会导致另一个实例属性的改变,这与我们平时所需要的要求不和
所以最常见的方法是采用自定义模式:构造函数用来定义一些个性的属性,而原型则定义一些共有的属性和方法
动态原型模式:在定义原型属性时先判断属性是否存在,如果不存在,才创建,这样的好处是可以减少代码的执行次数,在第一次调用构造函数就创建了原型属性,此后则可不需执行中间的代码
在上面的模式都不合用时,考虑parasitic构造,与工厂模式类似,但是创建时实例时需要new,这个模式用于特殊情况的为对象创建构造函数
稳妥函数模式:不适用new和this,避免其他应用程序对数据的调用,限制访问数据的途径,只能通过方法获得属性值,最后两种方法实例与构造函数之间没有关系,instanceOf操作符 对其没有意义