学习前端系列-JavaScript

JavaScript

JavaScript是一门脚本编程语言,它可以在网页上实现复杂的功能,网页展现给你的不再是简单的静态信息,实时的内容更新,交互式的地图,2D/3D 动画,滚动播放的视频,等等。
JavaScript标准称为ECMAScript标准, 最新正式版ES6

第一步

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
// example
// <p>玩家1:小明</p>
var para = document.querySelect('p');
para.addEventListener('click', updateName);
function updateName() {
var name = prompt('请输入一个新名字:');
para.textContent = '玩家1:' + name;
}

// API分为浏览器API,第三方API
浏览器API分为
文档对象模型API(DOM(Document object Model))
地理位置API
画布(Canvas)和WebGL 创建2D和3D图像
HTMLMediaElement和WebTRC等影音类API
第三方API 如Twitter API

// 添加js
// 内部的js 在</body>前插入<script></script>
// 外部的js <head><script src="script.js"></script></head>
// 内联的js <button onclick="fun()">click me</button> function fun(){} 不要这样做

// 变量
如果不用var声明 name='wcg' 表示全局变量 'use strict'; 强制使用var, 不使用会报ReferenceError
var name = 'wcg'; 字符串 10, 数字 true, 布尔 ['a', 'b'] 数组 {name: 'wcg', age: 100} 对象
typeof name; 获取变量类型

js不区分整数 浮点数
NaN 表示Not a Number
Infinity 表示超过js表达的最大值
null 等于python中的None
undefined 表示未定义

全局变量, js默认有一个全局对象window
var name = 'wcg';
name
window.name // name变量绑定到window的一个属性
function foo() {
alert('foo');
}
foo();
window.foo();

ES6
let 代替 var 声明块级作用域的变量
const PI = 3.14; 定义常量
let [x, y, z] = ['w', 'c', 'g']

// 操作符
=== !==

// 字符串
var name = `这是一个
多行
字符串`; es6标准
字符串拼接
var message = '你好,' + name;
var message = '你好,${name}'; es6

var name = 'wcg';
引号和python一样, 转义用\
字符型转数字 Number(name);
数字转字符串 'num'; 或 num.toString();
name.length;
name[0];
name.indexOf('cg'); 查找子字符串, 找不到返回-1
name.slice(0, 2); wc js切片第二个是可选
name.slice(1); cg 没有会到末尾
name.substring(); 同slice
name.toLowerCase(); 调用不会修改原字符串, 而是返回一个新的
name.toUpperCase();
name.replace('g', 'c');

// 数组
var name = new Array(1, 2, 3)
var name = ['w', 'c', 'g']
name[0];
name.length;
字符串转数组 var myArray = myData.split(',');
数组转字符串 var myString = myArray.join(''); 或 var myString = myArray.toString();
name.push('g'); 末尾
name.pop();
name.shift('w'); 开头
name.unshift('w');
name.sort();
name.reverse();
name.splice(2, 3, 'google', 'baidu'); 从2开始, 返回删除的3个数
name.concat([1, 2, 3]) 数组连接

// Map ES6
var m = new Map(['wcg', 100], ['abc', 90])
m.set('admin', 80)
m.get('wcg')
m.delete('admin')

// Set ES6
var s = new Set([1, 2, 3, 3])
s.add(4)
Set{1, 2, 3, 4}
s.delete(3)

// iterable ES6
array map set 用for of遍历
for infor of 区别
for ... in循环由于历史遗留问题, 它遍历的实际上是对象的属性名称, 一个Array数组实际上也是一个对象, 它的每个元素的索引被视为一个属性
var a = ['A', 'B', 'C'];
a.name = 'wcg';
for (var x in a) {
console.log(x); //'0', '1', '2', 'name'
}
name 不应该包含在内, for of 完全修复了这个问题, 只返回本身的元素

a.forEach(function (element, index, array)) {
//pass
}

// 高阶函数
var arr = [1, 2, 3];
arr.map(Sting); // ['1', '2', '3']

arr.reduce(function (x,y) {
return x + y;
}); // 6

var r = arr.filter(function (s) {
return s > 2;
}); // 3

var s = arr.sort();

// 闭包
function sum(arr) {
var sum = function() {
return arr.reduce(function (x, y) {
return x + y;
});
}
return sum;
}

// 箭头函数相当于匿名函数, 且简化了函数定义 ES6
function (x) {
return x*x;
}
x => x*x

x => {
if (x > 0) {
return x * x;
}
}

(x, y) => x * x + y * y;
() => 3.14 无参数
x => ({foo: x}) 对象

// 生成器
function* fib(max){
var
t,
a=0,
b=1,
n=0;
while (n<max) {
yield a;
[a, b] = [b, a+b];
n ++;
}
return;
}

for (var x of fib(10)) {
console.log(x);
}

try {
r1 = yield ajax('http1', data1);
r2 = yield ajax('http2', data2);
success(r2);
}
catch (err) {
handle(err);
}

基础要件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// 条件 && 与 || 或 ! 非
if (true) {
//pass
} else if (true) {
//pass
} else {
//pass
}

switch (choice) {
case 'sunny':
//pass
break;
case 'rainy':
//pass
break;

default:
//pass;
}

// 三元运算符
var greeting = (isBirthday)?'Happy birthday':'Good morning'

// 循环
for (var i = 0; i < cats.length; i++) {
//pass
}

break; continue;

while (true) {
//pass
}

do {
//pass
} while (true);

// 函数
function draw() {
//pass
}
draw();

function foo(x) {
l = arguments.length //获取所有参数
}

ES6
function foo(a, b, ...rest) {
console.log(rest) //Array[] 额外参数
}

匿名函数, 一般用来处理事件程序, 如点击
myButton.onclick = function() {
alert('hello');
}

var myfunc = function() {} 可以赋值给变量
myfunc()

btn.onclick = displayMessage; 函数后面的括号叫函数调用运算符, 直接调用的话用displayMessage(), 否则当点击时才调用这个函数

带参数, 需要放在新的匿名函数里面
btn.onclick = function () {
displayMessage('hello');
}

// 返回
console.log(); return

// 事件
btn.addEventListener('click', displayMessage);
btn.addEventListener('click', function () {
//pass
});
btn.removeEventListener('click', displayMessage);

事件对象
function func(e) {
e.target //事件对象上
}

阻止默认行为
e.preventDefault();

事件冒泡
e.stopPropagation();

// 异常
try {
//pass
} catch (e) {
//pass
} finally {
//pass
}

throw new Error(''); 抛出异常

// 回调
setTimeout(test, 1000); //1000毫秒后执行test

// jQuery
简化DOM操作 $

// underscore
提供完善的函数式编程的方法, 比如在object中使用map _
_.map({a:1, b:2, c:3}, (v, k) => k + '=' + v); // ['a=1', 'b=2', 'c=3']
_.map(obj, function (value, key){return;});
_.every([-1, 2, 3], (x) => x > 0); //false
_.some([-1, 2, 3], (x) => x > 0); true
_.max([]) _.min([]);
_.groupBy(socres, function(x) {});
_.shuffle([1, 2, 3, 4]); 随机打乱顺序
_.sample([1, 2, 3], 2); [1,3]
... 其他见文档

对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
// 创建对象, js对象是无序的
js属性名包含特殊字符, 就必须用""括起来, 且不能用点, 用object['middle-school']
'name' in wcg; 判断属性是否存在, 可继承
wcg.hasOwnProperty('name') 判读自身是否拥有
js的对象键必须是字符串

var objectName = {
member1Name: member1Value, // 属性
member2Name: function () {}, // 方法
}

this 指当前代码运行时的对象

js没有用于创建class类的声明, 用构建函数来定义
function Person(name) {
this.name = name;
this.greeting = function() {
alert('hello' + this.name);
};
}
var person1 = new Person('wcg');

Object() 构造函数
var person2 = new Object(); 空对象
person2.name = 'wcg'; 往里填充

create()方法 基于现有对象创建新的对象实例
var person3 = Object.create(person2);

js是一种基于原型(prototype)的语言, 每一个对象拥有一个原型对象, 对象的属性和方法定义在Object的构造器函数之上的prototype属性上
在传统的OOP中, 定义类, 此后创建对象实例时, 类中的定义的所有属性和方法都被复制到实例中, 但在js中, 而是在对象实例和构造器之间建立一个链接(__proto__属性, 从构造函数的prototype属性派生), 之后通过上溯原型链, 在构造器中找到这些属性和方法, 如果没找到继续上溯, 直到最后没找到, undefined

person3.constructor 返回用户构造此实例对象的构造函数

一般在构造体定义属性 在prototype属性中定义方法
function Test(a, b, c) {
this.a = a;
}

Test.prototype.x = function () {}

// apply
function getAge() {
//pass
}
var wcg = {}
getAge.apply(wcg, []); 参数

js通过原型式的继承
function test(a, b, c, d) {
Test.call(this, a, b, c); //调用Test构造函数, 绑定this变量
this.d = d;
}
test.prototype = Object.create(Test.protytype); 设置test的原型和构造器
test.prototype.constructor = Test;
test.prototype.greeting = function () {};

最好通过中间函数F实现
function inherits(child, parent) {
var F = function () {
F.prototype = parent.prototype;
child.prototype = new F();
child.prototype.constructor = child;
}
}
inherits(test, Test)
test.prototype.greeting = function () {};

// class ES6
function Student(name) {
this.name = name;
}
Student.prototype.hello = function () {return;}
// class
class Student{
constructor(name){
this.name = name;
}
hello(){
return;
}
}
// class继承
class PrimaryStudent extends Student {
constructor(name, grade){
super(name); //super调用父类的构造方法
this.grade = grade;
}
myGrade(){}
}

JSON对象就是基于js的对象

最简单的xmlhttprequest请求, ajax请求是异步的, 要通过回调函数获得响应
var requestURL = 'https://blog.itswcg.com';
var request = new XMLHttpRequest();
request.open('GET', requestURL);
request.responseType = 'json';
request.send();

request.onload = function() {
var response = reqeust.response; 事件处理, 只有请求成功后才触发load事件
}

ajax 浏览器同源策略 url的域名必须和当前页面完全一致, 域名 协议http 端口要完全一样
h5 CORS 设置header Access-Control-Allow-Origin: *
还要设置Access-Control-Request-Method: GET, POST ...

// Promise 承诺将来会执行 ES6
new Pormise(test).then(function (result) {
console.log('success');
}).catch(function (reason) {
console.log('failed')
})

Promise.all([p1, p2]).then() 同时执行p1 p2, 完成后才执行then
Promise.race([p1, p2]).then() p1 p2 执行速度快的then, 慢的执行结果被丢弃

// Canvas h5
<canvas id="test-canvas" width="300" height="200"></canvas>
var canvas = document.getElementById('test-canvas');
var ctx = canvas.getContent('2d'); 2d
var gl = canvas.getElementById('webgl'); 3d

// JSON 转换
var mystr = JSON.stringify(myjson);
var myjson = JSON.parse(mystr);

// 标准对象
typeof 可以判断number, boolean, string, function, undefined
判断Array使用Array.isArray(arr);
判断null myVar === null;
判断全局变量 typeof window.myVar === 'undefined';
判断局部变量 typeof myVar === 'undefined';

数字转字符串
123..toString();
(123).toString();

Date
var now = new Date();
now;
now.getFullYear();
now.getTime();
var d = new Date(2018, 11, 13, 19, 32, 123); js月份是0~11

客户端API

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
IE10, chrome, safari, firefox 支持ES6

window 是载入浏览器的标签, 不止充当全局作用域, 而且表示浏览器窗口
navigator 表示浏览器存在web上的状态和标识, 如获取摄像头, 地理位置
document 是载入窗口的实际页面

window 操作
window.innerWidth;
window.innerHeight;

navigator.appName 浏览器名称
navigator.appVersion 浏览器版本
navigator.language 浏览器设置的语言
navigator.platform 操作系统类型
navigator.userAgent 浏览器设定的User-Agent字符串

var width = window.innerWidth || document.body.clientWidth;

screen.width 屏幕宽度 以像素为单位
screen.height 屏幕高度 以像素为单位
screen.colorDepth 返回颜色位数 如8 16 24

// location对象表示当前页面的URL信息
location = 'http://www.example.com:8080/path/index.html?a=1&b=2#TOP'
location.protocol; // 'http'
location.host; // 'www.example.com'
location.port; // '8080'
location.pathname; // '/path/index.html'
location.search; // '?a=1&b=2'
location.hash; // 'TOP'

location.reload(); //重新加载当前页面
location.assign('https://blog.itswcg.com') //加载新的

DOM操作
var link = document.querySelector('#id1'); 返回第一个a
var links = document.querySelectorAll('a'); 返回所有, 数组
document.getElementById('id');
document.getElementByTagName('p');
document.getElementsByClassName('red');
document.cookie; //获取cookie

var cs = link.children;
var first = link.firstElementChild; last

var para = document.querySelector('#id2'); 更新html
p.innerHTML = 'ABC' //设置文本
p.innerHTML = 'ABC <span style="color:red">RED</span>'; //设置html,要避免xss攻击
p.innerText = '<scrip></script>' //html自动编码, 无法设置js节点
p.textContent = '' //返回所有文本

var para = document.createElement('p'); 创建节点
para.textContent = '';
sect.appendChild(para);
sect.removeChild(para);
sect.parentNode.removeChild(sect); 删除自己
sect.insertBefore(para, p); 插入p之前

para.style.color = 'white'; 操作css
para.style.backgroundColor = 'black';
para.setAttribute('class', 'highlight');

var input = document.getElementById('email'); 操作表单
input.value; 用户输入的值
mon.checked; true or false 复选框
input.value = 'wcg'; 设定值

网络请求
fetch(url).then(function(response){
return response.text()
}).then(function(text){
poemDisplay.textContent = text;
})

cookie 是过时的
现在用web storage和indexedDB api
未来 cache api

localStorage.setItem('name', 'wcg');
var myName = localStorage.getItem('name');
localStorage.removeItem('name');

let db; 块级作用域
window.onload = function() {
let request = window.indexedDB.open('notes', 1);
let objectStore = db.createObjectStore('notes', {keyPath:'id', autoIncreament:true});
objectStore.createIndex('title', 'title', {unique:false});
objectStore.createIndex('body', 'body', {unique:false});
}
----------本文完,感谢您的阅读----------