# JavaScript
javaScript是一门世界上最流行的脚本语言,一个合格的后端人员,必须精通JavaScript
<script>
//....
<script>
test.js
alert("hello,world");
test.html
<script src="js/test.js">script>
<script type="text/javascript">script>
测试代码
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<script src="js/hj.js">script>
<script type="text/javascript">script>
head>
<body>
body>
html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<script>
// 1. 定义变量 变量类型 变量名 = 变量值
var score = 1 ;
//alert(num)
// 2. 条件控制
if (score > 60 && score < 70){
alert("60~70");
}else if(score > 70 && score < 80){
alert("70~80");
}else{
alert("other")
}
script>
head>
<body>
body>
html>
数值,文本,图形,音频,视频
var name;
js不区分小数和整数,Number
123//整数123
123.1//浮点数123.1
1.123e3//科学计数法
-99//负数
NaN //not a number
Infinity // 表示无限大
‘abc’ “abc”
true,false
&& 两个都为真,结果为真
|| 一个为真,结果为真
! 真即假,假即真
=
1,"1"
== 等于(类型不一样,值一样,也会判断为true)
=== 绝对等于(类型一样,值一样,结果为true)
这是一个JS的缺陷,坚持不要使用 == 比较
须知:
尽量避免使用浮点数进行运算,存在精度问题
Java的数组必须是相同类型的对象~,JS中不需要这样
//保证代码的可读性,尽量使用[]
var arr = [1,2,3,4,5,'hello',null,true];
//第二种定义方法
new Array(1,2,3,4,5,'hello');
注意:取数字下标:如果越界了,就会 报undefined
对象是大括号,数组是中括号
每个属性之间使用逗号隔开,最后一个属性不需要逗号
// Person person = new Person(1,2,3,4,5);
var person = {
name:'Tom',
age:3,
tags:['js','java','web','...']
}
取对象值
person.name
> "Tom"
person.age
> 3
\'
\n
\t
\u4e2d \u##### Unicode字符
\x41 Ascall字符
//tab 上面 esc下面
var msg =
`hello
world
你好呀
nihao
`
//tab 上面 esc下面
'use strict'
let name='zs';
let age=15;
let msg=`你哈呀${
name},你的年龄是${
age}`
str.length
//注意,这里是方法,不是属性了
student.toUpperCase();
student.toLowerCase();
[)
student.substring(1)//从第一个字符串截取到最后一个字符串
student.substring(1,3)//[1,3)
Array可以包含任意的数据类型
var arr = [1,'a',3,'ccasd',5,6];//通过下标取值和赋值
注意:假如给arr.lennth赋值,数组大小就会发生变化~,如果赋值过小,元素就会丢失
通过元素获得下标索引
arr.indexOf(3)
2
字符串的"2"和数字2是不同的
截取Array的一部分,返回的一个新数组,类似于String中substring
push:压入到尾部
pop:弹出尾部的一个元素
unshift:压入到头部
shift:弹出头部的一个元素
(3)["B","C","A"]
arr.sort()
(3)["A","B","C"]
(3)["A","B","C"]
arr.reverse()
(3)["C","B","A"]
注意:concat()并没有修改数组,只是会返回一个新的数组
若干个键值对
var 对象名 = {
属性名:属性值,
属性名:属性值,
属性名:属性值
}
//定义了一个person对象,它有四个属性
var person = {
name:"Tom",
age:3,
email:"[email protected]",
score:66
}
Js中对象,{…}表示一个对象,建制对描述属性xxx:xxx,多个属性之间用逗号隔开,最后一个属性不加逗号!
JavaScript中的所有的键都是字符串,值是任意对象!
使用一个不存在的对象属性,不会报错!undefined
<script>
var arr=[2,5,0,1,3,8,6,5];
for (let number of arr) {
console.log(number);
}
</script>
let map=new Map([['zs',18],['ls',20],['ww',20]])
for (let mapElement of map) {
console.log(mapElement)
}
let set=new Set([1,3,6,9])
for (let setElement of set) {
console.log(setElement)
}
<script>
function abc(x){
if(x>0){
return x;
}else{
return -x;
}
}
</script>
function(x){…}这是一个匿名函数。但是可以把结果赋值给abs,通过abs就可以调用函数
<script>
let abc=function (x) {
if(x>0){
return x;
}else{
return -x
}
}
</script>
<script>
let abc=function (x) {
if(typeof x!=='number'){
throw 'Not a Number!'
}
if(x>0){
return x;
}else{
return -x
}
}
</script>
arguments
是JS免费赠送的关键字,是一个数组,代表传进方法的所有参数<script>
let abc=function (x) {
console.log('x==>'+x)
for(let i=0;i<arguments.length;i++){
console.log(arguments[i])
}
if(x>0){
return x;
}else{
return -x
}
}
</script>
<script>
let aaa=function (x,y,...rest) {
console.log(x)
console.log(y)
console.log(rest)
}
</script>
<script>
function f() {
let x=1;
console.log(x)
}
console.log(x)
</script>
function f() {
let x=1;
console.log(x)
}
function f1() {
let x='a';
console.log(x)
}
f();
f1();
<script>
function f() {
let x=1;
console.log(x)
f1()
function f1() {
console.log(x)
}
}
</script>
假设在JavaScript中,函数查找变量从自身函数开始~, 由“内”向“外”查找,假设外部存在这个同名的函数变量,则内部函数会屏蔽外部函数的变量。
<script>
function f() {
let x=1;
console.log('outer'+x)
f1()
function f1() {
x='a'
console.log('inner'+x)
}
}
</script>
<script>
function f() {
var x="x"+y;
console.log(x);
var y="y";
console.log(x);
}
</script>
说明:js执行引擎,自动提升了y的声明,但是不会提升变量y的赋值
等价
<script>
function f() {
var y;
var x="x"+y;
console.log(x);
y="y";
console.log(x);
}
</script>
这个是在javascript建立之初就存在的特性。 养成规范:所有 的变量定义都放在函数的头部,不要乱放,便于代码维护;
<script>
var x=1;
function f() {
console.log(x);
}
function f2() {
console.log(x);
}
f();
f2();
console.log(x);
</script>
<script>
var x='1231412';
alert(x)
alert(window.x)//默认所有的全局变量都会绑定在windows对象下
</script>
alert() 这个函数本身也是一个window的变量;
javascript实际上只有一个全局作用域,任何变量(函数也可以视为变量),假设没有在函数作用范围内找到,就会向外查找,如果在全局作用域都没有找到,就会报错 Refrence
<script>
function a(){
for (var i = 0; i < 10; i++) {
console.log(i)
}
console.log(i+1)//存在问题:i出了这个作用域还可以使用
}
</script>
<script>
function a(){
for (let i = 0; i < 10; i++) {
console.log(i)
}
console.log(i+1)//存在问题:i出了这个作用域还可以使用
}
</script>
注:
1、null的类型是object,Array的类型也是object,如果我们用typeof将无法区分出null、Array和通常意义上的object——{}
2、typeof操作符可以判断出number
、boolean
、string
、function
和undefined
;
3、判断Array
要使用Array.isArray(arr);
4、判断null
请使用myVar === null;
5、判断某个全局变量是否存在用typeof window.myVar === 'undefined'
6、函数内部判断某个变量是否存在用typeof myVar === 'undefined'
number、boolean和string都有包装对象。没错,在JavaScript中,字符串也区分string类型和它的包装类型。包装对象用new创建
var n = new Number(123); // 123,生成了新的包装类型
var b = new Boolean(true); // true,生成了新的包装类型
var s = new String('str'); // 'str',生成了新的包装类型
特点:虽然包装对象看上去和原来的值一模一样,显示出来也是一模一样,但他们的类型已经变为object
了!所以,包装对象和原始值用=比较会返回false
typeof new Number(123); // 'object'
new Number(123) === 123; // false
typeof new Boolean(true); // 'object'
new Boolean(true) === true; // false
typeof new String('str'); // 'object'
new String('str') === 'str'; // false
在javascript中,一切皆为对象,任何js支持的类型都可以用JSON表示
正则表达式是一种用来匹配字符串的强有力的武器。它的设计思想是用一种描述性的语言来给字符串定义一个规则,凡是符合规则的字符串,我们就认为它“匹配”了,否则,该字符串就是不合法的。
在正则表达式中,如果直接给出字符,就是精确匹配
\d
:可以匹配一个数字
00\d
可以匹配007
,但无法匹配00A
;\d\d\d
可以匹配010
;\w
:可以匹配一个字母或数字
\w\w
可以匹配js
;.
:可以匹配任意字符
js.
可以匹配jsp
、jss
、js!
等等*
:表示任意个字符(包括0个)+
:表示至少一个字符?
:表示0个或1个字符{n}
:表示n个字符{n,m}
:表示n-m个字符\d{3}\s+\d{3,8}
\d{3}
表示匹配3个数字,例如’010’;\s
可以匹配一个空格(也包括Tab等空白符),所以\s+
表示至少有一个空格,例如匹配' '
,'\t\t'
等;\d{3,8}
表示3-8个数字,例如’1234567’'-'
是特殊字符,在正则表达式中,要用'\'
转义,所以,上面的正则是\d{3}\-\d{3,8}
[]
[0-9a-zA-Z\_]
可以匹配一个数字、字母或者下划线[0-9a-zA-Z\_]+
可以匹配至少由一个数字、字母或者下划线组成的字符串,比如a100
,0_Z
,js2015
等等;[a-zA-Z\_\$][0-9a-zA-Z\_\$]*
可以匹配由字母或下划线、$
开头,后接任意个由一个数字、字母或者下划线、$组成的字符串,也就是JavaScript允许的变量名;[a-zA-Z\_\$][0-9a-zA-Z\_\$]{0, 19}
更精确地限制了变量的长度是1-20个字符(前面1个字符+后面最多19个字符)A|B
可以匹配A或B,所以(J|j)ava(S|s)cript可以匹配JavaScript
、Javascript
、javaScript
或者javascript
^
表示行的开头,^\d
表示必须以数字开头$
表示行的结束,\d$
表示必须以数字结束类
:类是对象的类型模板,例如,定义Student
类来表示学生,类本身是一种类型,Student
表示学生类型,但不表示任何具体的某个学生;实例
:实例是根据类创建的对象,例如,根据Student
类可以创建出xiaoming、xiaohong、xiaojun
等多个实例,每个实例表示一个具体的学生,他们全都属于Student类型JavaScript不区分类和实例的概念,而是通过原型
(prototype)来实现面向对象编程
var robot = {
name: 'Robot',
height: 1.6,
run: function () {
console.log(this.name + ' is running...');
}
};
robot
对象有名字,有身高,还会跑,有点像小明,干脆就根据它来“创建”小明得了!于是我们把它改名为Student
,然后创建出xiaoming
var Student = {
name: 'Robot',
height: 1.2,
run: function () {
console.log(this.name + ' is running...');
}
};
var xiaoming = {
name: '小明'
};
xiaoming.__proto__ = Student;
xiaoming
的原型指向了对象Student,看上去xiaoming
仿佛是从Student
继承下来的:xiaoming.name; // '小明'
xiaoming.height;//1.2
xiaoming.run(); // 小明 is running...
xiaoming
有自己的name属性,但并没有定义run()方法。不过,由于小明是从Student继承而来,只要Student
有run()方法,xiaoming
也可以调用:
JavaScript的原型链和Java的Class区别就在,它没有“Class”的概念,所有对象都是实例,所谓继承关系不过是把一个对象的原型指向另一个对象而已。
如果你把xiaoming
的原型指向其他对象:
var Bird = {
fly: function () {
console.log(this.name + ' is flying...');
}
};
xiaoming.__proto__ = Bird;
xiaoming
已经无法run()了,他已经变成了一只鸟:xiaoming.fly(); // 小明 is flying...
在JavaScrip代码运行时期,你可以把xiaoming
从Student
变成Bird
,或者变成任何对象。
Object.create()
方法可以传入一个原型对象,并创建一个基于该原型的新对象,但是新对象什么属性都没有,因此,我们可以编写一个函数来创建xiaoming:// 原型对象:
var Student = {
name: 'Robot',
height: 1.2,
run: function () {
console.log(this.name + ' is running...');
}
};
function createStudent(name) {
// 基于Student原型创建一个新对象:
var s = Object.create(Student);
// 初始化新对象:
s.name = name;
return s;
}
var xiaoming = createStudent('小明');
xiaoming.run(); // 小明 is running...
xiaoming.__proto__ === Student; // true
原型
,指向它的原型对象
obj.xxx
访问一个对象的属性时,JavaScript引擎先在当前对象上查找该属性,如果没有找到,就到其原型对象上找,如果还没有找到,就一直上溯到Object.prototype对象
,最后,如果还没有找到,就只能返回undefined。
var arr = [1, 2, 3];
arr ----> Array.prototype ----> Object.prototype ----> null
Array.prototype
定义了indexOf()、shift()
等方法,因此你可以在所有的Array
对象上直接调用这些方法function Student(name) {
this.name = name;
this.hello = function () {
alert('Hello, ' + this.name + '!');
}
}
var xiaoming = new Student('小明');
xiaoming.name; // '小明'
xiaoming.hello(); // Hello, 小明!
注意,如果不写new
,这就是一个普通函数,它返回undefined
。但是,如果写了new,它就变成了一个构造函数,它绑定的this
指向新创建的对象,并默认返回this
,也就是说,不需要在最后写return this
;。
xiaoming
的原型链xiaoming ----> Student.prototype ----> Object.prototype ----> null
xiaoming ↘
xiaohong -→ Student.prototype ----> Object.prototype ----> null
xiaojun ↗
class Person{
constructor(name) {
this.name=name
}
run(){
alert(this.name+"can run")
}
}
var zz=new Person('zz');
zz.run();
class Person{
constructor(name) {
this.name=name
}
run(){
alert(this.name+"can run")
}
}
var zz=new Person('zz');
zz.run();
class Children extends Person{
constructor(name,age) {
super(name);
this.age=age;
}
say(){
alert(this.name+"是个孩子")
}
}
var c=new Children('cc',20);
c.say()
BOM:浏览器对象模型
navigator
对象表示浏览器的信息,最常用的属性包括
注:大多数时候,我们不会使用navigator对象,因为会被人为修改!不建议使用这些属性来判断和编写代码
screen对象表示屏幕的信息,常用的属性有
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.assign()**。
如果要重新加载当前页面,调用**location.reload()**
document
对象表示当前页面。由于HTML在浏览器中以DOM
形式表示为树形结构,document对象
就是整个DOM树的根节点。document.title="phx132"
<dl id="drink-menu" style="border:solid 1px #ccc;padding:6px;">
<dt>摩卡dt>
<dd>热摩卡咖啡dd>
<dt>酸奶dt>
<dd>北京老酸奶dd>
<dt>果汁dt>
<dd>鲜榨苹果汁dd>
dl>
<script>
var menu = document.getElementById('drink-menu');
var drinks = document.getElementsByTagName('dt');
var i, s;
s = '提供的饮料有:';
for (i=0; i<drinks.length; i++) {
s = s + drinks[i].innerHTML + ',';
}
console.log(s);
script>
由于HTML文档被浏览器解析后就是一棵DOM树,要改变HTML的结构,就需要通过JavaScript来操作DOM。始终记住DOM是一个树形结构
<div id="father">
<h1>h1h1>
<p id="p1"> p1p>
<p class="p2"> p2p>
div>
删除节点的步骤:先获取父节点,再通过父节点删除自己
// 拿到待删除节点:
var self = document.getElementById('to-be-removed');
// 拿到父节点:
var parent = self.parentElement;
// 删除:
var removed = parent.removeChild(self);
removed === self; // true
当你遍历一个父节点的子节点并进行删除操作时,要注意,children属性是一个只读属性,并且它在子节点变化时会实时更新。
<div id="parent">
<p>Firstp>
<p>Secondp>
div>
<script>
var parent = document.getElementById('parent');
parent.removeChild(parent.children[0]);
parent.removeChild(parent.children[1]); // <-- 浏览器报错
script>
浏览器报错:parent.children[1]不是一个有效的节点。原因就在于,当 First
节点被删除后,parent.children的节点数量已经从2变为了1,索引[1]已经不存在了。因此,删除多个节点时,要注意children属性时刻都在变化。
我们获得了某个Dom节点,假设这个dom节点是空的,我们通过innerHTML就可以增加一个元素了
例如,,那么,直接使用innerHTML = 'child’就可以修改DOM节点的内容,,相当于“插入”了新的DOM节点
<div id="list">
<p id="java">Javap>
<p id="python">Pythonp>
<p id="scheme">Schemep>
<p id="js">JavaScriptp>
div>
<script>
var list = document.getElementById('list'),
var haskell = document.createElement('p');
//haskell.setAttribute("id","haskell");
haskell.id = 'haskell';
//haskell.setAttribute("innerText ","Haskell");
haskell.innerText = 'Haskell';
list.appendChild(haskell);
script>
<div id="list">
<p id="java">Javap>
<p id="python">Pythonp>
<p id="scheme">Schemep>
div>
<script>
var list = document.getElementById('list'),
var ref = document.getElementById('python'),
var haskell = document.createElement('p');
haskell.id = 'haskell';
haskell.innerText = 'Haskell';
list.insertBefore(haskell, ref);
script>
文本框----text
下拉框----select
单选框----radio
多选框----checkbox
隐藏域----hidden
密码框----password
...
<body>
md5加密密码,表单优化
<head>
<title>Titletitle>