浅学一下JavaScript
编写位置
- 写在html的script标签里面
- 写在标签的onclick属性中
- 写在超链接的href属性中
- 写在外部文件中(推荐)
<script type='text/javascript'>
alert("message");
</script>
<button onclick="alert("message");">
clock
</button>
<a href="javascript:alert("message");">
clickMe!
</a>
<script type="text/javascript" src='location.js'>
<script>
注:script标签写在文档最后,不然会出现先编译代码然后没得运行的情况(实在要写在head里面的话也可以绑定到window.onload事件上去)
输出
<script>
alert("message");
document.write("message");
console.log("message");
</script>
字面量、变量、标识符
字面量是可以直接使用的不可以改变的量(就是单纯的值罢了)
变量就是变量。。。
<script>
var a=250;
var a='hello';
</script>
其中a为变量,250,‘hello’为字面量
标识符就是我们可以自主命名的用于标注的东西,比如上面的a就是标注一个变量的标识符(标识符底层是用utf-8编码的,所以理论上中文可以做标识符。。。。。。)
数据类型
- number:数值(Number.MAX_VALUE保存最大值)
- string:字符串
- boolean:布尔值(真或假)
- Null:只有一个值就是null,表示空
- Undefined:undefined,当变量声明但是没赋值的情况变量等于这东西
运算符
既然是借鉴c写的,那应该差不多,就不管了
if语句,switch语句,for循环,break,continue等
这些条件控制语句和c一模一样
对象
对象就是数据的有机组合。
对象是数据描述的载体。
对象包含两个要素:属性(变量),方法(函数)
对象分类
- 内建对象:ES标准中定义的对象(比如各种数据类型)
- 宿主对象:由js运行环境提供的对象,比如document
- 自建对象:自己写的对象
对象的操作
<script>
var obj = new Object();
obj.name = 'Andrew';
obj.name = 'Andrew821';
obj1 = {name:"Andrew",age:0};
console.log(obj.name);
var key = 'name';
console.log(obj[key]);
delete obj.name;
"name" in obj => False
<\script>
使用工厂方法批量生产对象
function creatPerson(name,age){
var obj = new Object();
obj.name =name;
obj.age = age;
return obj;
}
其实就是写函数创建对象罢了
构造函数
就是用函数实现构造不同的对象类型,和工厂方法的区别只是调用方式不一样,加个new就可以了。
function Person(name,age){
var obj = new Object();
obj.name =name;
obj.age = age;
return obj;
}
var per = new Person("A",1);
这个时候per的对象就不再是object了,而是Person
构造函数中的this
function Person(){
this.name = 'A';
}
var per = new Person();
per.name --> 'A'
使用这种方法可以真正实现方便的构造特定对象
注:
A instanceof B
方法可以判断A和B是否是同一种对象- 如果对象中有方法,可以定义为全局函数,这样的话就会重复创建太多方法
原型对象
原型对象可以用于批量修改同类型的对象的属性或方法
有意思的是,即使原型也有原型,但不会无限递归
toString
对象的toString方法的返回值就是直接返回对象结果,因此可以通过修改这个方法来修改直接返回对象的结果
垃圾回收
使用obj=null
来对obj对象所占空间进行回收
this
指向函数执行的上下文对象。
一句话:谁最后调用this所在对象,this就指向谁
函数
万物都是对象,函数也是
<script>
var fun = new Function("console.log('Hello');");
fun();
var obj = {a:1,b:2};
function fun2(x){
return x.a+x.b;
}
var res = fun2();
var fun3 = function(a,b){
document.write(a+b);
}
fun3();
</script>
call,apply方法
懒得打了。。。
argument
数组
var arr = new Array();
arr[0] = 0;
arr[1] = 1;
var arr2 = [1,2,3,3,2,3];
var arr3 = new Array(1,2,3,3,2,1,"hello");
console.log(arr[0]);
数组里面保存的是对象,所有对象。
数组的方法(push,pop,unshift,shift,foeEach,slice,splice等)的话,自己上网查去。
正则表达式
DOM
document object model,可以让我们随心所欲操作网页
DOM简介
文档和对象都比较好理解,不过模型相对较新,可以使用图论中的树来理解:
不难看出,结构包含节点和关系
相关操作
- document:文档对象
文档对象的方法有:
var x = document.getElementById("id");
x.innerHTML = 'hello';//修改获得的对象的对应属性即可
var x1 = document.getElementsByTagName("id");
var x2 = document.getElementsByName("id");
x2.id;//除了class属性,其他的html对象属性都可以用这种方式读取,class用className读取
事件
结合上图,可按照如下的方式绑定处理函数
1:不分离
<button onclick="alert("message");"> clock </button>
2:分离
<button id="id"> clock</button>
<script>
var x = document.getElementById("id");
x.onclick = function(){
alert("message");
}
</script>
修改内联样式
因为内联样式优先级比较高,因此基本上改了就会显示
某人心血来潮用JavaScript写的线段树
page.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>
基于线段树的区间求和程序
</h1>
<form>
<label>
输入区间序列:
<input type="text" class="input" id="Input">
<button id="Button">计算</button>
</label>
</form>
</body>
<script src="alog2.js"></script>
</html>
alog2.js
let x = document.getElementById("Button");
x.onclick = function (){
let y = document.getElementById("Input");
let a = y.value.split(',');
let n = a.length;
let data = [0];
for(let i=0;i<n;++i){
data.push(Number(a[i]));
}
function mkArr(len, init){
let arr = [];
arr.length = len;
arr.fill(init);
return arr;
}
let sums = mkArr((n + 10) << 1, 0);
function pushup(rt){
sums[rt] = sums[rt<<1] + sums[rt<<1|1];
}
function buildtree(l, r, rt) {
if (l === r) {
sums[rt] = data[l];
return;
}
let mid = (l + r) >> 1;
buildtree(l, mid, rt << 1);
buildtree(mid + 1, r, rt << 1 | 1);
pushup(rt);
}
function querySum(l, r, nl, nr, rt){
if(l<=nl && nr <= r){
return sums[rt];
}
let mid = (nl+nr)>>1;
let res = 0;
if(mid >= l)res += querySum(l,r,nl,mid,rt<<1);
if(mid < r)res += querySum(l,r,mid+1,nr,rt<<1|1);
return res;
}
buildtree(1, n, 1);
alert("区间[1," + n + "]的和为:" + querySum(1,n,1,n,1));
}