20170308
数据类型和变量
数据类型 (共有六种)
undefined null number string boolean object
简单数据类型
undefined null number string boolean
复杂数据类型
object
typeof
检测结果可以是
undefined number object string boolean function
==
会自动转换数据类型 ===
则不会
例如:
alert(undefined == null) // ture;
var a = 1,
b = "1";
alert(a == b) //true
undefined
的意思是变量未定义或者函数参数找不到值返回的值
null
是一个空对象指针
alert(undefined == null) // true
但是也有特殊的,例如
NaN == NaN // false
NaN === NaN //false
NaN
(not a number)跟任何一个值不相等,包括其本身,唯一判断的方法是isNaN()
isNaN(NaN) // true
字符串
方法 | 描述 |
---|---|
concact() | 连接字符串 |
toString() | 转换成字符串 |
match() | 匹配字符串指定的值或者与正则匹配的值 |
replace(a,b) | 替换字符串或者正则表达式的值a为正则表达式或者字符串,b为要替换的内容 |
charAt(index) | 返回指定位置字符串的值 |
slice(a,b) | 返回a到b位置的字符串 |
subString(a,b) | 截取索引a到b但是不包括b |
split() | 将字符串分割成数组,同join()相反 |
toUpperCase() | 将小写字母转成大写 |
toLowerCase() | 将大写字母转成小写 |
ES6新增内容
多行字符串
console.log(`hello
world
`) /* hello
word*/
字符串连接
var name = 'jack',
age = '20',
message = `你好,${jack},你今年${age}岁了`;
console.log(message) //你好,jack,你今年20岁了'
20170309
数组
方法 | 描述 |
---|---|
indexOf(a) | 返回a在数组中的位置 |
slice(0,2) | 截取index为0开始,2结束但不包括2的值 |
splice(0,2,'a','b') | 删除index为0后面两个值并添加a,b |
shift() | 从数组顶端删除一个元素 |
unshift() | 从数组顶端插入元素 |
push() | 从数组底部插入元素 |
pop() | 从数组底端删除一个元素 |
sort() | 数组按着默认顺序排序 |
reverse() | 数组按相反顺序排序 |
concact() | 合并两个数组 |
join() | 将数组分割成字符串 |
20170315
Map和Set
Map和Set 都是ES6新增的数据结构,具体参看阮一峰的ES6入门之Map和Set
学习过程中发现Array.from()
的用法:
Array.from
函数(数组):
从类似数组的对象或可迭代的对象返回一个数组。
语法
Array.from (arrayLike [ , mapfn [ , thisArg ] ] );
参数
arrayLike
必需。
类似数组的对象或可迭代的对象。
mapfn
可选。要对 arrayLike 中的每个元素调用的映射函数。
thisArg
可选。指定映射函数中的 this 对象。
备注
arrayLike
参数必须是具有编制索引的元素和 length 属性的对象或可迭代对象,如 Set 对象。
对数组中每个元素调用了可选映射函数。
数组迭代方法
every()、some()、filter()、map()、foreach();
evey() 跟 some() 方法类似,不同之处在于,every 所有的都满足选择条件才返回 true,some() 有一项返回
true,其结果则为 true,有点类似真值表“与、或”的关系。filter()是返回符合函数条件返回true的数组。map()是返回每次函数调用结果组成的数组。foreach()没有返回值,对指定的数组运行指定的函数。
var arr = [1,2,3,4,5,6,7];
var result = arr.every(function (item,index,arr) {
return (item>2);
});
console.log(result); //false;因为不是所有的值都大于2
//同样的使用 some 方法则返回 ture;
var result1 = arr.map(function (item,index,arr) {
return item*2;
})
console.log(result1) //[2,4,6,8,10,12,14]
var result2 = arr.foreach(function (item,index,arr) {
return console.log(item);
})
console.log(result2) //1,2,3,4,5,6,7
20170327
对象
JavaScript的对象是一种无序的集合数据类型,它由若干键值对组成。
访问对象属性的点语法跟方括号的区别
var person = {
name:'gogo'
}
一般来说,访问对象属性时都使用点表示法,这也是很多面向对象语言中通用的语法。不过在javascript中,也可以使用方括号表示法来访问对象的属性。
首先需要说明的是,对象的属性名称就是以字符串来保存的。
例如 person.name = "Nike"
为person定义了一个名为name
的属性,name
本身是以字符串的形式保存的。
用Object.keys(person)
验证,结果是["name"]
,说明name
属性确实是以字符串来保存的。
在使用方括号语法时,应该把属性以 字符串的形式 放在方括号中,如:
alert(person["name"]); //gogo
alert(person.name); //gogo
从功能上说,这两种方法没有任何区别。但方括号语法有一个优点:可以通过变量来访问属性,如:
var propertyName = 'name';
alert(person[propertyName]); //gogo
如果属性名中包含会导致语法错误的字符,或者属性名是关键字或者保留字,也可以使用方括号表示法**。如:
person['first name'] ='gogo'; //first name包含一个空格
但是!!建议使用点表示法,除非必须使用变量来访问属性。
另外,[ ]方括号访问的属性名时,可以在程序运行时创建和修改属性,点操作符就不行。
eg1:
var addr="";
for(i=0;i<4;i++){
addr += customer["address"+i]+'\n';
}
eg2:
function addStock(portfolio,stockname,shares){
portfolio[stockname]=shares;
}
循环
for ... in
存在弊端。例如一个数组
var a = ['A', 'B', 'C'];
a.name = 'Hello';
for (var x in a) {
alert(x); // '0', '1', '2', 'name'
}
for ... in
循环将把name包括在内,但Array
的length
属性却不包括在内。
for ... of
循环则完全修复了这些问题,它只循环集合本身的元素:
var a = ['A', 'B', 'C'];
a.name = 'Hello';
for (var x of a) {
alert(x); // 'A', 'B', 'C'
}
然而,更好的方式是直接使用iterable
内置的forEach
方法遍历数组,为每个元素调用指定的函数。以Array
为例:
var a = ['A', 'B', 'C'];
a.forEach(function (value, index, array) {
// value: 指向当前元素的值
// index: 指向当前索引
// array: 指向Array对象本身
alert(element);
});
20170331
函数
- 函数没有重载
- 函数声明与函数表达式
- 函数内部属性
- 函数属性和方法
函数没有重载
eg:
function addSomeNum (num) {
return num + 100;
}
function addSomeNum (num) {
return num + 200;
}
addSomeNum(100); //300
实质上浏览器是这样解析的
var addSomeNum = function (num) {
return num + 100;
};
addSomeNum = function (num) {
return num +200;
}
addSomeNum(100); //300
在创建第二个函数的时候,实际上是覆盖了引用第一个函数的变量addSomeNum
。
函数声明与函数表达式
主要区别在于浏览器在解析时执行顺序不同。
eg:
alert(color('red')); //red
function color (color) {
return color;
};
在解析过程中,函数声明有一个提升的过程(function declaration hoisting)。函数会被放到源代码的顶部。
所以上述代码在浏览器的实际解析顺序是
function color (color) {
return color;
};
alert(color('red')); //red
然而函数表达式的解析并不提升函数本身。
alert(color('red')); //Uncaught TypeError: color is not a function
var color = function (color) {
return color;
}
上述代码之所以报错是因为浏览器在解析过程中是先声明再赋值,这里的执行顺序是这样的
var color;
alert(color('red')); //因为变量还没有被赋值,即被调用,所以这里会报错,下面的赋值过程不再进行
函数的内部属性
主要有两个特殊对象:arguments
和 this
arguments
是类数组对象,包含传入函数的所有参数。有一个 callee
属性,用来指向拥有这个 arguments
对象的函数。这个属性的作用是消除函数名和函数的执行之间的耦合关系,主要是在经典阶乘函数中。需要注意的是 arguments
在 严格模式中无效。
this
引用的是函数据以执行的环境对象——也就是 this
值。简单来说就是谁调用的函数,this
就指向谁
eg:
var birth = 1992;
var obj = {
birth: 1990,
getAge: function () {
var b = this.birth; // 1990 此处this指向obj,因为是obj调用的getAge方法
var fn = function () {
return new Date().getFullYear() - this.birth; //此处this指向window。因为fn函数被当作普通函数调用的。
}
return fn();
}
};
console.log(obj.getAge()); //25
函数的属性和方法
length
和prototype
length
是函数希望接收参数的个数,一般是形参的个数。其中,
arguments.callee.length
是形参也就是期望接收的参数的个数。而argument.length
是实参也就是实际传入参数的个数。
prototype
是指向一个对象的引用,这个对象称为“原型对象”。每一个函数都包含不同的原型对象。当将函数用做构造函数时,新创建的对象会从原型对象上继承属性。
apply()
和 call()
方法
函数调用的两种方法。用途是在特定的作用域中间接调用函数。其中,他们的第一个实参都是要调用函数的母对象(调用函数的上下文,通过this
来获得)。比如,要想以o
对象的方法调用函数f()
,可以写成
f.call(o);
f.apply(o);
每行代码与如下代码相似(假设o对象中没有m方法)
o.m = f; //将f存储为o的临时方法
o,m(); //调用临时方法,并不传入参数
delete o.m; //删除临时方法
对于call
来说其余参数是要传入待调用函数的值。比如,以对象o的方法调用函数f(),并传入两个参数,可以写成
f.call(o,1,2)
apply
的区别在于把要传入待调用函数的实参全部放到一个数组中
f.apply(o,[1,2])