JavaScript
JavaScript是一门脚本编程语言,它可以在网页上实现复杂的功能,网页展现给你的不再是简单的静态信息,实时的内容更新,交互式的地图,2D/3D 动画,滚动播放的视频,等等。 JavaScript标准称为ECMAScript标准, 最新正式版ES6
第一步
// 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 in 和 for 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);
}
基础要件
// 条件 && 与 || 或 ! 非
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]
... 其他见文档
对象
// 创建对象, 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
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});
}