Chapter3
- typeof操作符的操作数可以是变量, 也可以是字面量
typeof name,typeof 10 typeof null -> object因为特殊值null被认为是一个空对象的引用(null值表示一个空对象指针)- 变量没声明的话, 直接用报错
xxx is not defined var name; // name没有进行初始化 typeof name -> undefinedtypeof age -> undefined //age 没有声明- null更多用来初始化对象
类型转换
- !!"" -> false
- null 和 undefined没有toString()方法, 其他类型都有toString()
字符串的toString()方法返回一个字符串的副本 - toString(进制数), 默认为10
- null和undefined没有toString()方法, undefined.toString()报错
Uncaught TypeError: Cannot read property 'toString' of undefined String()可以转换所有类型数据为字符串; String(null) => "null"; String(undefined) => undefined;- Boolean()转换
在if(condition)语句中,condition可以是任意表达式, 而且这个表达式的求值结果并不一定是布尔值,ECMAScript会自动调用
Boolean()转换函数将表达式结果转换为布尔值 - break直接跳出整个循环; continue跳出本次循环
forEach如何跳出循环???"
###类型转换(解释即可)
解释了下面的每一结果的原因,
- ['a','b','c'] + ['2', '3','4']
- 3<4<2
- toString() 和 toValue()
值传递和应用传递
- 按值访问和按引用访问
- 参数传递:按值传递
- 函数的参数传递和变量复制一样
- 所谓
对象的引用就是栈内存中指向堆内存对象的一个指针值 - 参见文章
- ES中函数的参数传递都是
值传递
类型判断
typeof基本类型检测: undefined, boolean, string, number, functioninstanceof引用类型检测
- 所有引用类型值都是Object的实例
- instanceof 检测基本类型 return false, 因为基本类型不是变量
- typeof /12/ => object
正则表达式也是对象 - /12/ instanceof RegExp => true
正则表达式
- typeof /12/ => object
正则表达式也是对象 - /12/ instanceof RegExp => true
第五章 引用类型
5.1 Object类型
- 在最后一个属性后添加
,会在IE7以及opera中导致错误 - 在使用对象字面量语法时,属性名也可以使用字符串.数值属性名会自动转换为字符串
var person = {}<=>var person = new Object()在通过对象字面量定义对象时,实际上不会调用Object构造函数- 方括号语法访问对象属性值的有点是: 可以通过变量来访问属性
JavaScript var propertyName = 'name' person[propertyName] //在for循环中根据key值作为变量, 访问对象属性值 // 如果属性名中包含会导致语法错误的字符,或者属性名使用的是关键字或保留字,也可以使用方括号表示法。例如:person["first name"] = "Nicholas"; 由于"first name"中包含一个空格,所以不能使用点表示法来访问它。然而,属性名中是可以包含非字母非数字的,这时候就可以使用方括号表示法来访问它们。通常,除非必须使用变量来访问属性,否则我们建议使用点表示法
5.2 Array类型
- 利用length属性也可以方便地在数组末尾添加新项,如下所示:
var colors = ["red", "blue", "green"];
colors[colors.length] = "black";
colors[colors.length] = "brown";
//由于数组最后一项的索引始终是length-1,因此下一个新项的位置就是length。每当在数组末尾添加一项后,其length属性都会自动更新以反应这一变化。
- ES5 中检测数组的方法: Array.isArray()
- 转换
toString()将数组转换为字符串, [1,2,3,4,5].toString()会调用数组中每一项的toString()方法,之后将其拼接为一个字符串, 中间以逗号分隔
- 改写toString()方法和验证上一步骤:
var person1 = {
toLocaleString: function() {
return 'john'
},
toString: function() {
return 'john2'
}
}
var person2 = {
toLocaleString: function() {
return 'zhangsan'
},
toString: function() {
return 'zhangsan2'
}
}
var people = [person1, person2]
console.log(people)
console.log(people.toString())
console.log(people.toLocaleString())
- 如果数组中的某一项的值是null或者undefined,那么该值在join()、toLocaleString()、toString()和valueOf()方法返回的结果中以空字符串表示
- join()
var colors = ["red", "green", "blue"];
colors.join('=') // "red=green=blue="
colors // ["red", "green", "blue"];
var colors = ["red", "green", "blue", undefined];
colors.toString() // "red,green,blue,"
-
sort 1. 默认情况下,sort()方法按升序排列数组项——即最小的值位于最前面,最大的值排在最后面。 为了实现排序,sort()方法会调用每个数组项的toString()转型方法,然后比较得到的字符串,以确定如何排序。 即使数组中的每一项都是数值,sort()方法比较的也是字符串,如下所示
var values = [0, 1, 5, 10, 15]; values.sort(); alert(values); //0,1,10,15,5
2. 自定义排序函数
> 比较函数接收两个参数,
> 如果第一个参数应该位于第二个之前则返回一个负数,
> 如果两个参数相等则返回0,
> 如果第一个参数应该位于第二个之后则返回一个正数。
> 以下就是一个简单的比较函数:
```JavaScript
function compare(value1, value2){
if (value1 < value2) { return -1}
else if (value1 > value2 ) {return 1}
else {return 0}
}
var values = [0, 1, 5, 10, 15];
values.sort(compare) // values => [0, 1, 5, 10, 15];
// 注意: 排序之后, 数组的值与之前不同
// reverse()和sort()方法的返回值是经过排序之后的数组
```
3. 对于数值类型或者其valueOf()方法会返回数值类型的对象类型,可以使用一个更简单的比较函数。这个函数只要用第二个值减第一个值即可(正序)
```JavaScript
function compare(value1, value2){
return value1 - value2;
}
```
8. 操作方法
1. concat 连接两个数组, arr.concat() => arr保持不变, 返回的是arr的副本
2. slice 不改变原数组
3. splice 改变原数组
9. 位置方法
1. indexOf() 查找使用 ===
2. lastIndexOf 同上
3. 使用indexOf()和lastIndexOf()方法查找特定项在数组中的位置非常简单,支持它们的浏览器包括IE9+、Firefox 2+、Safari 3+、Opera 9.5+和Chrome。
10. 归并(求和)操作
1. reduce()
2. reduceRight()
3. 在对对象数组的某一个属性求和的时候注意:
4. 参考链接
5. 这两个方法都接收两个参数:一个在每一项上调用的函数和(可选的)作为归并基础的初始值- <JS高程 5.2.9节 归并方法>
6. // A cleaner way to accomplish this is by providing an initial value:
JavaScript var arr = [{x:1}, {x:2}, {x:4}]; arr.reduce(function (prev, cur) { return prev + cur.x; }, 0); // 7
- The first time the anonymous function is called, it gets called with
(0, {x: 1})and returns0 + 1 = 1. 函数第一次调用的时候, 传入(prev, cur)的值是(0, {x: 1})- The next time, it gets called with
(1, {x: 2})and returns `1 + 2 = 3 .- It's then called with (3, {x: 4}), finally returning
- 如果不传入最后的0, 函数第一次调用,传入
(prev, cur)的值是({x:1}, {x: 2}), 返回值就是"[object Object]2".- 如果有一个操作数是对象、数值或布尔值,则调用它们的toString()方法取得相应的字符串值,然后再应用前面关于字符串的规则。对于undefined和null,则分别调用String()函数并取得字符串"undefined"和"null - <JS高程 3.5.5节 加性操作符>"
5.5 Function类型
- 解析器在向执行环境中加载数据时,对函数声明和函数表达式并非一视同仁。解析器会率先读取函数声明,并使其在执行任何代码之前可用(可以访问);至于函数表达式,则必须等到解析器执行到它所在的代码行,才会真正被解释执行
- 在代码开始执行之前,解析器就已经通过一个名为函数声明提升(function declaration hoisting)的过程,读取并将函数声明添加到执行环境中。对代码求值时,JavaScript引擎在第一遍会声明函数并将它们放到源代码树的顶部。所以,即使声明函数的代码在调用它的代码后面,JavaScript引擎也能把函数声明提升到顶部
- 函数声明
alert(sum(10,10));
function sum(num1, num2){ return num1 + num2; }
- “unexpected identifier”(意外标识符)错误 => 变量未声明,就直接调用
- 因为ECMAScript中的函数名本身就是变量,所以函数也可以作为值来使用。也就是说,不仅可以像传递参数一样把一个函数传递给另一个函数,而且可以
将一个函数作为另一个函数的结果返回 - arguments.callee 表示函数本身
function factorial(num){
if (num <=1) { return 1; }
else return num * arguments.callee(num-1)
}
- arguments.callee.caller 表示函数的调用者
function outer(){
inner();
}
function inner(){
alert(arguments.callee.caller);
}
outer();
- 函数的名字仅仅是一个包含指针的变量而已。因此,即使是在不同的环境中执行,全局的sayColor()函数与o.sayColor()指向的仍然是同一个函数
- IE、Firefox、Chrome和Safari的所有版本以及Opera 9.6都支持caller属性。当函数在严格模式下运行时,访问arguments.callee会导致错误。ECMAScript 5还定义了arguments.caller属性,但在严格模式下访问它也会导致错误,而在非严格模式下这个属性始终是undefined。定义这个属性是为了分清arguments.caller和函数的caller属性。以上变化都是为了加强这门语言的安全性,这样第三方代码就不能在相同的环境里窥视其他代码了。严格模式还有一个限制:不能为函数的caller属性赋值,否则会导致错误
- 函数的length表示函数希望接受的参数个数
- call 与 apply扩充函数作用域的最大好处:
对象不需要与方法有任何耦合关系 - call, apply, bind
- new Number('10') 与 Number('25')不一样. 后者是类型转换函数, 参见第三章类型转换
typeof new Number('10') => 'object'typeof Number('10') => 'number'
5.6.3 String类型
-
位置
- charAt
- charCodeAt 获得字符编码
- 可以使用方括号加数字索引来访问字符串中的特定字符, 'abcd'[1], IE8及以上支持
-
操作
- concat => +
- slice() , 参数[开始位置, 结束位置)
- substring(), 参数[开始位置, 结束位置) 在对字符串操作时候, 与上述相同
- substr(), 参数[开始位置, 返回字符串个数]
- slice()、substr()和substring() 指定一个参数时候(非负数), 返回值都是从指定位置到字符串最后一个字符(包含最后一个)的子字符串, 传递一个参数是负数时, var stringValue = "hello world"
- stringValue.substr(-3) => stringValue.substr(11-3) => stringValue.substr(8)
IE的JavaScript实现在处理向substr()方法传递负值的情况时存在问题,它会返回原始的字符串。IE9修复了这个问题。 - stringValue.slice(-3) => stringValue.slice(11-3) => stringValue.slice(8)
- stringValue.substring(-3) => stringValue.substring(0) => 返回值就是整个字符串了
-
传递第二个参数是负数时, var stringValue = "hello world"
- stringValue.slice(3, -4) => slice(3,7)
- stringValue.substring(3, -4) => stringValue.substring(3, 0) => stringValue.substring(0,3)
substring()方法会把第二个参数转换为0,使调用变成了substring(3,0),而由于这个方法会将较小的数作为开始位置,将较大的数作为结束位置,因此最终相当于调用了substring(0,3) - substr()也会将第二个参数转换为0,这也就意味着返回包含零个字符的字符串,也就是一个空字符串.
因为substr第二个参数代表的是返回字符串的个数,既然第二参数变为0了, 因此也就返回0个字符, 也就是空字符串
- 利用indexOf 查询字符串中某元素的所有位置
var stringValue = "Lorem ipsum dolor sit amet, consectetur adipisicing elit"; var positions = new Array(); var pos = stringValue.indexOf("e"); while(pos > -1){ positions.push(pos); pos = stringValue.indexOf("e", pos + 1); } alert(positions); //"3,24,32,35,52"- trim()去除字符串两端空格实现:`IE9+、Firefox 3.5+、Safari 5+、Opera 10.5+和Chrome支持
String.prototype.trim = function() { return this.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); }
5.7 单体内置对象
- Math 1. Math.floor() 2. Math.ceil() 3. Math.round() 4. Math.min.apply(Math, 数组) 5. Math.max.apply(Math, 数组) > 这个技巧的关键是把Math对象作为apply()的第一个参数,从而正确地设置this值。然后,可以将任何数组作为第二个参数 6. Math.max(11,22,33,44,55). Math.max()的参数不能是数组,因此如果比较数组的话, 需要把数组作为apply的参数传入. 7. Math.random() 返回值: [0, 1) 与Math.floor配合可以得到[2, 10] 或 其它区间
```JavaScript
function selectFrom(lowerValue, upperValue) {
var choices = upperValue - lowerValue + 1;
return Math.floor(Math.random() * choices + lowerValue);
}
var num = selectFrom(2, 10);
alert(num); // 介于2和10之间(包括2和10)的一个数值
var colors = ["red", "green", "blue", "yellow", "black", "purple", "brown"];
var color = colors[selectFrom(0, colors.length-1)];
alert(color); // 可能是数组中包含的任何一个字符串
```
第23章 离线应用与客户端存储
- 23.3 数据存储
- Cookie 1. cookie的key 和value都必须是URL编码的??? 2. cookie与session如何进行配合 3. 怎么验证该多个请求是同一个回话中发出的呢?和token进行比较呢??
- 变量赋值
这说明JavaScript实际上只有一个全局作用域。任何变量(函数也视为变量),如果没有在当前函数作用域中找到,就会继续往上查找,最后如果在全局作用域中也没有找到,则报ReferenceError错误。
'use strict';
var old_alert = window.alert;
window.alert = function(){ }
- 变量提升: 变量提升时,函数声明的变量名字和值都会提升,而函数表达式只提升名字。
demo();
test();
function demo(){
console.log('demo');
}
var test = function(){
console.log('test');
};
/*结果: VM2970:3 Uncaught TypeError: test is not a function(…)*/