快速入门
==
会自动转换数据类型,然后再进行比较,不建议使用。
===
不会自动转换数据类型,类型不一致就是false。
NaN
与所有值都不相等,包括自己,用isNaN()
判断。
浮点数比较大小看差值是否小于某个阈值。
null
表示空,undefined
表示未定义。
对象是键值对组成的无序集合。
不用var
声明的变量是全局变量,用'use strict'
模式限制。
字符串
反引号包裹的字符串支持换行,${name}
支持替换字符串。
字符串不可变,允许修改不过无效,s.length
是字符串长度,支持下标访问。
var s = 'hello, world!';
s.substring(0, 5); //'hello'
s.substring(7); //'world!'
s.indexOf('World'); // 7
s.toLowerCase(); //
s.toUpperCase(); //
数组
数组可越界访问,自动改变大小,不过不建议这样做。支持下标访问,可修改内容。
a.indexOf(内容); //找不到返回-1
a.sclice(0, 4); //就是substring,如果不传参数就是复制原数组
push和pop向数组最后添加或者删除元素,空数组仍可pop,返回undefined。
对应的头部操作是unshift和shift。
a.sort(); //对数组排序
a.reverse(); //反序
a.splice(pos, length, ...); //从pos开始删除length个元素,从pos添加...元素,返回值是删除的元素。
a.concat(...); //连接数组,参数可是元素或数组,不修改原数组,返回新数组。
a.join('-'); //用指定字符连接数组元素,返回字符串
对象
如果属性名包含特殊字符,要用引号扩住,且访问该属性时要用下标,不能用点运算符。
直接添加属性,用delete删除属性,用in检查是否拥有某一属性(含继承来的),用hasOwnProperty()检查是否拥有自己的属性。
delete xiaoming.age;
'name' in xiaoming;
xiaoming.hasOwnProperty('name');
条件和循环
基本和c++一样…
JavaScript把null
、undefined
、0
、NaN
和空字符串
”视为false
,其他值一概视为true
。
for(var o in array);
这里如果array增加新的属性,也会输出,但是array.length却不变。
Map和Set
var m = new Map();
m.set('asdg', 345);
m.get('asdg');
m.delete('asdg');
var m1 = new Map(['das', 123], ['gfd', 234]);
var s1 = new Set();
var s2 = new Set([1, 2, 5]);
s2.add(6);
s2.delete(6);
Map和Set无法使用下标,用iterable
。
具有iterable
类型的集合可以通过新的for(var o of set)
循环来遍历。
还可以用forEach()
,它接收一个函数作为参数。
var m = new Map();
n.forEach(function(value, key, m){
//函数体
//set没有key,前两个参数都是value
//数组一次是值,下标,数组名
//可以忽略一些参数
}
);
函数
JavaScript函数可以像变量一样使用。
function func(x){
//函数体
return x; //如果没有return,会返回undefined;
}
//func()是一个对象,func是指向该函数的变量
//也可这么写
var func = function(x){
//函数体
return x;
}
函数有默认参数arguments
,代表传进来的所有参数,类似数组但不是数组,arguments.length
可得到参数的数目。
rest
参数要用...
标识,代表匹配后剩下的参数。
JavaScript的函数定义有个特点,它会先扫描整个函数体的语句,把所有申明的变量“提升”到函数顶部:
变量作用域:内层覆盖外层,从内向外查找,外不可访问内。
JavaScript默认有一个全局对象window
,不在任何函数内的变量具有全局作用域,被绑定到window
的一个属性,函数也是如此。
const
和let
声明的变量都具有块级作用域,var声明的具有函数级作用域。
解构赋值:注意层次对应,可用来提取需要的元素。
对象方法
this有点迷,可用call或者apply指定方法的this。
function getAge() {
var y = new Date().getFullYear();
return y - this.birth;
}
var xiaoming = {
name: '小明',
birth: 1990,
age: getAge
};
xiaoming.age(); // 25
getAge.apply(xiaoming, []); // 25, this指向xiaoming, 参数为空,apply第二个参数是数组,call按顺序传入参数
高阶函数
参数是函数的函数叫做高阶函数。
map
定义在Array
中
function pow(x){
return x * x;
}
var a = [1, 2, 3];
var b = a.map(pow); b = [1, 4, 9];
reduce
接收两个参数,做累计运算。
var arr = [1, 3, 5, 7, 9];
arr.reduce(function (x, y) { //匿名函数
return x + y;
}); // 25
filter
接收一个函数用来过滤数组元素。
sort
接收一个函数指定排序规则,会修改原数组。
闭包
闭包就是将函数作为函数的返回值,并且调用时才执行函数。
箭头函数
解决了this指向问题。
// 两个参数:
(x, y) => x * x + y * y
// 无参数:
() => 3.14
// 可变参数:
(x, y, ...rest) => {
var i, sum = x + y;
for (i=0; i<rest.length; i++) {
sum += rest[i];
}
return sum;
}
generator
generator
和函数不同的是,generator
由function*
定义(注意多出的*号),并且,除了return语句,还可以用yield
返回多次。
遇到yield x
;就返回一个对象{value: x, done: true/false}
。
也可以用for of
来遍历generator。
标准对象
可用typeof
获取对象的类型,返回一个字符串,注意Array
,null
,{}
都是object
,因此只可区分number
,boolean
,string
,function
,undefined
。
包装对象:
var n = new Number(123); // 123,生成了新的包装类型
var b = new Boolean(true); // true,生成了新的包装类型
var s = new String('str'); // 'str',生成了新的包装类型
如果忘记加new
,仅仅是进行类型转换。
不要使用new Number()、new Boolean()、new String()创建包装对象;
用parseInt()或parseFloat()来转换任意类型到number;
用String()来转换任意类型到string,或者直接调用某个对象的toString()方法;
通常不必把任意类型转换为boolean再判断,因为可以直接写if (myVar) {…};
typeof操作符可以判断出number、boolean、string、function和undefined;
判断Array要使用Array.isArray(arr);
判断null请使用myVar === null;
判断某个全局变量是否存在用typeof window.myVar === ‘undefined’;
函数内部判断某个变量是否存在用typeof myVar === ‘undefined’。
Date
JavaScript的Date对象月份值从0开始,牢记0=1月。
RegExp
正则表达式
\d
:数字
\w
:数字或字母
\s
:空格
.
:任意一个字符
*
:任意个字符
+
:表示至少一个
{n}
:n个
{n,m}
:[n,m]个
^\d
:必须以数字开头
\d$
:必须以数字结束
创建RegExp对象:
var re1 = /ABC\-001/;
var re2 = new RegExp('ABC\\-001');
re1; // /ABC\-001/
re2; // /ABC\-001/
re1.test('234-234'); // false;
字符串分割:
'a,b;; c d'.split(/[\s\,\;]+/); // ['a', 'b', 'c', 'd']
分组提取子串:
如果正则表达式中定义了组,就可以在RegExp对象上用exec()方法提取出子串来。
贪婪匹配:
正则匹配默认是贪婪匹配,价格?
采用费贪婪匹配。
var re = /^(\d+?)(0*)$/;
re.exec('102300'); // ['102300', '1023', '00']
全局搜索:
var r1 = /test/g;
// 等价于:
var r2 = new RegExp('test', 'g');
每次匹配后从下一个位置开始下一轮匹配。
JSON
数据类型:
number:和JavaScript的number完全一致;
boolean:就是JavaScript的true或false;
string:就是JavaScript的string;
null:就是JavaScript的null;
array:就是JavaScript的Array表示方式——[];
object:就是JavaScript的{ … }表示方式。
字符串必须用双引号,且键也必须用双引号。
将JavaScript对象序列化:var s = JSON.stringify(Obj);
价格JSOn反序列化成JavaScript对象:var obj = JSON.parse('JSON');
面向对象编程
将对象的__proto__
属性指向另一个对象,实现继承。
Object.create()
方法可以传入一个原型对象,并创建一个基于该原型的新对象,但是新对象什么属性都没有。
原型继承
看得云里雾里,prorotype
那些东西太烦了,可以参考这里。
不过既然有更好的方式就不用学这个了吧。。。
class继承
就像是Java的语法,简单易懂。
class PrimaryStudent extends Student {
constructor(name, grade) {
super(name); // 记得用super调用父类的构造方法!
this.grade = grade;
}
myGrade() {
alert('I am at grade ' + this.grade);
}
}
浏览器
浏览器对象
- window对象不但充当全局作用域,而且表示浏览器窗口。
- navigator对象表示浏览器的信息。
- screen对象表示屏幕的信息。
- location对象表示当前页面的URL信息。
- document对象表示当前页面。由于HTML在浏览器中以DOM形式表示为树形结构,document对象就是整个DOM树的根节点。
用document对象提供的getElementById()和getElementsByTagName()可以按ID获得一个DOM节点和按Tag名称获得一组DOM节点:
document对象还有一个cookie属性,可以获取当前页面的Cookie。 - history对象保存了浏览器的历史记录,JavaScript可以调用history对象的back()或forward (),相当于用户点击了浏览器的“后退”或“前进”按钮。不建议再用了。