欢迎各位指导与讨论 : )
-------------------------待续-------------------------------
本文为笔者在学习时整理的笔记,如有错漏,恳请各位指出,共同进步O(∩_∩)O
第二章 在HTML中使用JavaScript
1 . script标签的默认type属性值为 text/javascript 其在http传输中的MIME Type通常为 application/x-javascript
2 . 使用转义字符防止script标签提早结束而报错 alert('<\/script>')
3 . 延迟脚本——其包含的脚本内容表示该脚本在执行过程中不会影响页面内容 浏览器会立即下载,但是延迟执行。若页面包含多个延迟脚本,则执行顺序难以确定,建议只包含一个延迟脚本
4 . 异步脚本——目的是让浏览器不要等到此脚本的下载和执行,从而异步加载页面其他内容,建议不要在异步脚本加载期间修改DOM。多个异步脚本之间的执行顺序也是难以确定
第三章 基本概念
1 . 若省略分号,则由解析器确定语句的结尾,但不推荐。添加分号能避免压缩造成的错误,同时也能减少解析器推测在哪里插入分号所带来的性能消耗
2 . ECMA变量是松散类型的 var hello 之类的操作会为变量保存一个undefined(Undefined类型只有一个值 即undefined)。同时,通过var 声明的变量会在所在函数退出后被销毁
3 . 五种基本数据类型 Undefined、Null、Boolean、Number、String(注 null == undefined // true )
4 . Null是第二个只有一个值的数据类型 即null,因为null值表示一个空的对象指针,因此 typeof null == 'object'
5 . 转换为布尔类型,NaN -> false,任何对象 -> true
6 . 不要测试某个特定的浮点数组(0.1 + 0.2 != 0.3)
7 . 最大和最小的数值为 Number.MAX_VALUE和Number.MIN_VALUE,可以用 isFinite(num) //true、false 判断是否为有穷
8 . 0除以0为NaN,正数除以0为Infinity,负数除以0为-Infinity,可以用 isNaN(xx) // true、false 判断它是否是一个数字(通过数值类型的转换)
9 . 有3个函数可以用于数值转换。Number( )可以接受任何类型的属性,parseInt( )和parseFloat( )用于把字符串转换为数值。 Number(null) // 0 , Number(undefined) // NaN , Number("") // 0 , Number('123') // 123 , Number('00123') // 123 , 若是对象,则先尝试调用对象的valueOf( )若失败,则尝试调用toString( )然后再尝试把字符串转换为数字
10 . parseInt( [mayBeNumber], [转换进制] ),同时parseInt( )会区分、忽略字符串中的字符和数字 parseInt('123') // 123 , parseInt('123blue') // 123 , parseInt('123.123') // 123 字符'.'被忽略了
11 . parseFloat( )会自动忽略开头的0,会忽略第二个字符 ' . ' 同时,parseFloat( )会解析一个可以解析为数值的字符串 parseFloat('3.12e7') // 31200000
12 . 某些版本浏览器的字符串连接: var a = 'Java' ; a += 'Script' ; 后台会先创建一个能容纳10个字符的新字符串,然后填充'Java'和'Script',然后销毁原来的'Java'和'Script'
13 . toString( [进制] )可以转换数值、布尔值、对象。 var num = 10 num.toString( 2 ) // '1010'
14 . String( )可以转换null和undefined var value1 = null; String(value1) // 'null' var value2; String(value2) // 'undefined'
15 . 逻辑非(!) ( !"blue" ) // false ( !"" ) //true ( !123 ) //false ( !NaN ) // true
16 . 乘性操作符,若乘积超过了ECMA的数值表示范围,则返回Infinity或者-Infinity Infinity与0相乘 // NaN
17 . 加性操作符,若只有一个操作数是字符串,则把另一个操作数转换为字符串然后进行字符串的拼接,可以使用圆括号来解决这个问题 Inifinty + -Inifinty // NaN 5 + '5' // '55' var num1 = 5; var num2 = 10; var sum = 'hello ' + (num1 + num2)
18 . 减性操作符,若有一个操作数是字符串,布尔值,null,undefined则先在后台调用Number( )再根据规则进行运算 5 - true // 4
19 . 逗号操作符,可以用于在一条语句中执行多条操作,当逗号操作符用于赋值时,则返回表达式中的最后一项 var num = (5, 21, 1, 0) // 0
20 . ECMA中函数命名参数不是必要的,我们可以通过arguments[x]来获取对应的参数
第四章 变量、作用域和内存问题
1 . 引用类型是保存的内存中的对象。JavaScript不允许直接访问内存中的位置,因此我们不能直接操作对象的内存空间。在操作对象时,实际上是在操作对象的引用而不是实际对象,引用类型的值是按引用访问的。但当我们要为对象添加属性时,操作的是实际对象
2 . 当一个变量向另一个变量复制引用类型的值时,同样也会将储存在变量对象中的值复制一份放到新变量的分配空间中。而这个值实际上是一个指针。因此这两个变量实际上会操作同一个对象。
3 . 参数传递中,若参数是一个基本类型参数,被传递的值会被复制给一个局部变量,也就是arguments对象中的一个元素。若是一个引用类型,则把这个值在内存的地址复制给对应的局部变量,即在函数内外,引用的是同一个对象。
4 . 在函数内部重新参数(参数为外部传递过来的对象),则此变量引用的是一个局部对象了,会在函数执行完毕之后立即被销毁。
function setName(obj){
obj.name = 'peng'
obj = new Object()
obj.name = "Greg"
}
var person = new Object();
setName(person);
alert(person.name) // 'peng'
5 . 检测基本类型时使用 typeof ,检测引用类型时使用 instanceof Object/Array/Regexp ,使用instanceof检测基本类型时,该操作符会始终返回 false ,因为基本类型都不是对象。
6 . 每个函数都有自己的执行环境,当执行流进入一个函数时,函数的环境会被推入到一个环境栈中。而在函数执行完之后,栈将其弹出,把控制权返回给之前的执行环境。同时保存在上一个环境的所有变量和函数定义也会被销毁。
7 . 作用域链:活动对象 -> 外部环境 -> 再上一层的环境 ... -> 全局环境。其中,活动对象在最开始只包含一个变量,即arguments对象。
8 . 任何环境都不能通过向下搜索作用域链进入另一个执行环境
9 . 使用 var 声明符,能够把变量自动添加到最接近的环境中,若初始化时没有使用var 操作符,则变量会被添加到全局环境中
10 . 管理内存:为了确保占用最少的内存让页面获得更好性能,我们应该将不再使用的数据的值设置为null(局部函数执行完后就离开其执行环境,因此无需我们手动解除引用),来释放其引用。其作用是,让其脱离执行环境,一遍垃圾收集器下次运行时将其回收。
第五章 引用类型
1 . 检测是否为数组 Array.isArray(value) ,若用 value instanceof Array 则在某些情况下得不到满意答案。
2 . 数组转换方法: toString( ) valueOf( ) 调用数组的这两个方法会返回数组中每个值的字符串拼接而成的一个以逗号分隔的字符串。
var colors = [ 'red', 'blue', 'green' ]
colors.toString( ) // red, blue, green
colors.valueOf( ) // red, blue, green
alert( colors ) //red, blue, green 自动调用方法
3 . 数组的栈方法:插入和移除操作只发生在数组的尾部 push、pop。其中,push可以接受任意数量的参数,并把它们逐个添加到数组尾部,返回修改后数组的长度。pop则直接从数组尾部移除最后一项,并返回并移除的项。
4 . 数组的队列方法:在列表的末端添加项 push( ),在数组头部移除项 shift( )。在数组头部添加:unshift( )
5 . 反序reverse( ), 重排序方法 sort( ),sort( ) 会调用数组项的 toString( )方法, 即使数组中的每一项都是数字,sort( ) 方法比较的也是字符串 [0,1,5,10,15].sort( ) // 0, 1, 10, 15, 5
6 . sort( )的比较函数,若第一个参数应该在第二个参数之前就返回一个负数,相反则返回一个正数
function compare(value1, value2){
if(value1 < value2){
return -1
}else if (value1 > value2){
return 1
}else{
return 0
}
}
/*** 简洁的写法 升序 ***/
function compare(v1, v2){
return v1 - v2
}
7 . concat( ) 若参数是一个数组,则把数组每一项都添加到末尾,若不是,则直接添加到末尾
color = ['red', 'green', 'blue']
color.concat('yellow', ['black', 'brown'])
// ['red', 'green', 'blue', 'yellow', 'black', 'brown']
8 . slice( ) 若只有一个参数,则返回从该参数(0 ~ 数组长度之间)开始的一段新数组副本,若有两个参数,则返回从第一个参数起,到第二个参数(不含第二个参数)的数组片段副本
9 . splice( ) 参数一:要删除的第一项的位置,参数二:要删除的项数。删除 splice( 0, 2 )从第一个开始,删除2位数组项;插入splice( 2,0,'green' ),在第三位插入一个'green';替换splice( 0, 1, 'green' ),删除一个增加一个(替换);增加splice( 0, 1, 'green', 'red' ) 删除1个增加2个
10 . 位置查找 indexOf( ), lastIndexOf( ) 都接受2个参数,查找的内容和开始位置,查找过程为严格相等 === ,找不到则返回 -1
11 . 迭代方法:以下这些方法都不会修改数组中包含的值。every( ):对数组中每一项运行指定函数,若每一项都返回true,则返回true;filter( ):对数组每一项运行指定函数,返回由返回true的数组项的数组。forEach( ):对数组每一项运行指定函数,没有返回值。map( ):对数组每一项运行指定函数,返回每次函数调用结果组成的数组。some( ):对数组每一项运行指定函数。若任一项返回true,则返回true
12 . Date构造函数接受一个表示日期的毫秒数,若参数为日期则会自动调用Date.parse( ) var t = new Date("May 25, 2004") 等价于 var t = new Date(Date.parse("May 25, 2004")) 。在调用Date构造函数不传递参数的情况下,新创建的对象会自动获得当前日期和时间 var now = new Date( ) 。
13 . Date.parse( ) 接受一个表示日期的字符串参数,然后尝试返回相应的毫秒数,或者会返回NaN。
14 . Date.UTC(年,月,日,时,分,秒),只有前两个为必须参数,一月为0以此类推。
15 . 日期格式化 toDateString( ) 显示星期几、月、日和年,toTimeString( ) 显示时分秒和时区,toUTCString( ) 完整的UTC日期
16 . 每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和方法,因此函数名实际上也是一个指向函数对象的指针 var f = function( ){...} // f instanceof Function -> true
17 . 解析器在向执行环境中加载数据时,对函数声明和函数表达式的处理有所不同。解析器会先读取函数声明并使其在执行任何代码之前可用,这是一个函数声明提升的过程,JS引擎会把声明函数放到源代码树的顶部。至于函数表达式,则必须等到解析器执行到所在代码是才会被执行。
// 可执行
alert(sum(1,2))
function sum(n1, n2){
return n1 + n2
}
// 报错
alert(sum(1, 2))
var sum = function(n1, n2){
return n1 + n2
}
18 . arguments的call.ee属性:该属性是一个指针,指向拥有这个arguments对象函数,该方法常用于函数的递归调用。
19 . 严格模式下直接访问cellee和caller都会报错,同时caller属性会返回调用者的源代码。
20 . 函数也是对象,每个函数都包含两个属性:length和prototype,其中length会返回函数希望接收的命名参数的个数 function sum(n1, n2){...} // sum.length -> 2
21 . apply( )和call( ) 这两个函数实际上等于设置函数体内this对象的值,它们两个的首个参数都是指向某对象的变量,call( )从第二个参数开始是一组参数队列,apply( )的第二个参数是一个参数数组
22 . bind( ) 这个方法会创建一个函数的实例,其this值会被绑定到传给bind( )函数的值
var o = {color: 'red'}
function say(){
console.log(this.color)
}
var say2 = say.bind(o)
say2() // 'red'
23 . 每个函数的 toString( ) 和 toLocaleString( )都会返回函数代码,返回格式因浏览器而异
24 . 引用类型和基本包装类型的主要区别是对象的生存期。引用类型的实例在执行流离开当前作用域之前都一直保持在内存中,而基本包装类型的对象只存在代码执行的瞬间,这意味着我们不能再运行时为基本类型的值添加属性和方法
var s1 = 'some text'
var s2 = s1.substring(2)
// 等价于
var s1 = new String('some text')
var s2 = s1.substring(2)
s1 = null // 被销毁
25 . 可以(不推荐)显式地调用Boolean、Number、String来创建基本包装类型的实例,在调用typeof会返回'object'
var value = '25'
var number = Number(value) // 转型函数
typeof number // number
var obj = new Number(value) // 构造函数
typeof obj // object
var falseObj = new Boolean(false);
var result = falseObj && true // true
// 对象在布尔比较中始终为true
26 . 基本类型的布尔值和Boolean对象间的比较,建议不要使用Boolean对象
falseObj = new Boolean(false)
falseValue = false
typeof falseObj // obj
typeof falseValue // boolean
falseObj instanceof Boolean // true
falseValue instanceof Boolean // false
27 . 基本类型Number格式化 toFixed( )、toExponmential( )、toPrecision( )
var num = 10;
num.toFixed(2) // 10.00
var num = 10.005
num.toFixed(2) // 10.01 自动舍入
num.toExponmential(1) // 1.0e+1 e表示法
var t = 99;
t.toPrecision(1) // 1e+2 ->自动选择格式转换
t.toPrecision(2) // 99
t.toPrecision(3) // 99.0
28 . 基本类型String的方法
// 1 . length 返回字符串的字符数量
var str = 'hello world'
str.length // 11
// 2 . charAt( )
str.charAt(1) // 'e'
// 3 . chatCodeAt( )
str.charCodeAt(1) // '101'
// 4 . trim( )
var s = ' hello world '
s.trim( ) // 'hello world
// 5. match( )
// 匹配字符串返回匹配成功的数组元素
// 6. search( )
// 返回第一个匹配元素的下标
29 . 在全局作用域中声明的所有变量和函数都成为了window对象的属性
第6章 面向对象的程序设计
1 . 数据属性:[[ Configurable ]] 能否通过delete删除属性并重新定义属性;[[ Enumerable ]] 能否通过 for-in 循环遍历属性;[[ Writeable ]] 能否修改;[[ Value ]] 该属性的数据值
2 . 修改属性默认特性: Object.defineProperty( anObj, anProperty, descriptor )。
var person = { };
Object.defineProperty(person, 'name', {
writable: false,
value: 'Peng'
})
console.log(person.name) // peng
person.name = 'hello'
console.log(person.name) // peng
3 . 一旦把configurable设置为false,则就不能再把它变回可配置了。同时,若不指定configurable,enumerable、writable、value则默认为false
4 . 访问器属性包含一对getter、setter函数。负责访问、写入属性
var book = {
year: 2004,
edition: 1
}
Object.defineProperty(book, 'year', {
get: function( ) {
return this.year
}
set: function(newValue ) {
this.year = newValue > 2016? newValue : 2016
}
})
5 . 定义多个属性的特性 Object.defineProperties( )
6 . 获得属性的特性的描述符 Object.getOwnPropertyDescriptor( anObj, anProperty )
7 . 创建对象的几种方法:工厂模式 用于封装创建过程 function create(name){var a = new Object( );//... } 构造函数 function Person(name){this.name = name} var p = new Person('a')
8 . new 操作符调用构造函数实际上会经历4个步骤,创建一个新对象、将构造函数内部的this指向新对象、执行构造函数代码、返回新对象
9 . 实例对象的Prototype属性指向这个实例的Prototype对象(原型对象),我们可以通过该对象为实例增添方法或属性。同时,该对象包含着实例的属性和方法,其中constructor属性指向实例的构造函数。
10 . isPrototypeOf( )来确定在实例和原型对象之间是否存在对应关系。通过 Object.getPrototypeof( ) 来获得实例的原型
11 . 使用delete操作符可以完全删除实例属性,让我们可以访问到原型中的属性 delete person.name
12 . in 操作符,只要属性存在于实例或者原型上都会返回true 'name' in person // true hasOwnProperty( ) 当属性只存在于实例上时才会返回true person.hasOwnProperty('name') // true
13 . Object.getOwnPropertyNames( ) 可以获取实例所有属性,包括不可枚举的属性
14 . 继承 SubType.prototype = new SuperType( )
第七章 函数表达式
1 . 函数声明一个重要特征是函数声明提升
2 . argument.callee 正在执行的函数指针,argumanet.caller 正在执行函数的调用者。
3 . 闭包:有权访问另一个函数作用域中的变量的函数。闭包中的this,除非特别声明,一般自动绑定为window。并且闭包只能取得函数中任何变量的最后一个值。且由匿名函数创建闭包中的this指向window对象
4 . 模仿块级作用域:立即执行函数
第八章 BOM
1 . BOM的核心对象是window,它表示一个浏览器实例。window对象既是JS访问浏览器窗口的一个接口,又是ECMA规定的Global对象。
2 . top对象始终指向最高(最外)层的框架,也就是浏览器窗口