与css文件一样,js文件也可以通过在head标签里直接写script标签以及代码(不建议),也可以通过外部引入(建议)。
<script src="./js/demo1.js">script>
注意:script标签必须成对出现。
123
123.1
1.23e6//科学计数法
-99
NaN //Not a Number
Infinity//表示无穷大
= 赋值
== 等于(类型不一样,值一样,也会判断为true)
=== 绝对等于(严格要求类型一样,值也一样)
isNaN()
来判断这个数是否是NaN
若干个键值对。
var 对象名 = {
属性名 : 属性值,
属性名 : 属性值,
属性名 : 属性值
}
js中的对象,{…}表示一个对象,键值对描述属性xxxx : xxxx,多个属性之间使用逗哈隔开,最后一个属性不加逗号。
使用一个不存在的对象属性,不会报错!undefined。
通过delete
可以动态的删减属性。
直接给新的属性添加值即可动态增加属性。
js中的所有键都是字符串,值是任意对象。
var person = {
name : "abc",
sex : "male",
age : 3,
score : 98
}
console.log('age' in person); //true
console.log('toString' in person) //true
console.log(person.hasOwnProperty('toString')); //false
console.log(person.hasOwnProperty('age')); //true
in
判断属性是否在这个对象中,包括从父类继承下来的。
hasOwnProperty
判断一个属性是否是这个对象自身拥有的。
for in则输出的是该数组的下标。
var arr = [9, 5, 7, 2 ,3 ,4, "ab", "cl"];
for (let i in arr) {
console.log(i); //0 - 7
}
for of输出的是该数组中具体的值。
for (let i of arr) {
console.log(i); //9 5 7..
}
定义方式一
function abs(x) {
if(x >= 0) {
return x;
} else {
return -x;
}
}
一旦执行到return代表函数结束,返回结果。
如果没有执行return,函数执行完也会返回结果,结果就是undefined。
定义方式二
var abs2 = function(x) {
if(x >= 0) {
return x;
} else {
return -x;
}
};
console.log(abs2("dsdasdas"));
function(x) {}这相当于一个匿名函数,因为没有函数名字。但是可以将结果赋值给变量,通过变量就可以调用函数。方式一和方式二等价。
js可以传递任意个参数,也可以不传递参数。
这种问题就和其他语言大相径庭,为了避免参数问题造成的困扰,我们可以对参数进行判断。
参数正确性判断
var abs2 = function(x) {
if (typeof x !== 'number') {
throw 'first argument is not number';
}
if(x >= 0) {
return x;
} else {
return -x;
}
};
console.log(abs2("dsdasdas"));
多个参数的情形
arguments
每个方法里都有这样一个属性。代表调用时传进来的所有参数,是一个数组。
在一个方法中定义变量,这个变量的生命域仅在该方法大括号里面,一旦大括号结束,该变量也就消失了。
如果引用一个变量,首先在它所在的方法内进行查找,如果没有,就在windows下找,还没有就报错。
不定义在任何方法下的变量,称为全局变量。该变量一旦定义了就会出现在widows下的属性中。
规范
由于我们所有的全局变量都会绑定到我们的windows上,如果不同js文件,使用了相同的全局变量,就会造成命名冲突,如何解决冲突呢?
var honorZApp = {}; //名字尽量能精确到可以确定为某一个人开发的,该变量是个存放键值对的容器。
honorZApp.name = "honorZ";
honorZApp.add = function (a, b) { //将你写的方法,属性之类的都以键值对添加到你自定义的全局变量中
return a + b;
}
console.log(honorZApp);
把自己的代码全部放入自己定义的唯一空间名字中,降低全局命名冲突的问题。
局部作用域(let)
for (let i = 0; i < 100; i++) { //建议设置为let,出了这个大括号就没用了
}
常量(const)
由于var和let变量都可以进行改变,我现在需要一种不可以改的只读数据,以前的处理方法是全是大写字母的变量代表常量,不要更改。是个约定,但是是可以改变的,新的特性引入了const关键字,设置为不可改的常量。
方法就是把函数放在对象里面。对象只有两个东西,属性和方法。
var person = {
name : "honorZ",
birthYear : 2000,
age : function () {
var now = new Date();
return now.getFullYear() - this.birthYear;
}
}
//属性
console.log(person.name);
//方法一定要带()才能运行。
console.log(person.age());
如果函数逻辑太复杂,我们可以将其分离出去,只不过要注意问题!
var person = {
name: "honorZ",
birthYear: 2000,
// age: getAge() 注意这里赋值不要加() age是个值,地址值,指向getAge,加了()就变成函数了
age : getAge
}
function getAge() {
var now = new Date();
return now.getFullYear() - this.birthYear;
}
console.log(person.name);
// console.log(person.age); 输出的是该函数
console.log(person.age()); //输出的是函数运行结果,加了()一定代表函数运行
上述问题,对于分离出去的getAger()
方法,如果直接进行调用。
getAge();
//输出NaN
原因在于,该方法看起来没有人调用,实际上调用它的是windows,方法里的this就指向了windows,但windows没有birthYear这个属性,所以输出NaN。
解决方法就是apply方法。
apply方法可以指定谁调用这个方法
// getAge().apply(person, []); 记住getAge()不能加(),加()它就运行去了,我们这时候需要的是方法的一个属性只需要方法名就ok
getAge.apply(person, []); //第一个参数是谁调用它,第二个参数是参数的值
getAge();//再进行一次,说明apply方法只是一次性用法,使用完就归回来了
var today = new Date
today.getTime() //时间戳 全世界统一 1970 1.1 0:00:00 毫秒数
//1627963917751
在JavaScript一切皆为对象,任何js支持的类型都可以用JSON表示;number,string…
格式:
var student = {
name : "honorZ",
age : 18,
sex : "male"
}
//对象转换为JSON字符串
var jsonStuden = JSON.stringify(student);
console.log(student);
console.log(jsonStuden);
//转换后的JSON字符串:{"name":"honorZ","age":18,"sex":"male"}
//JSON字符串解析为对象
var orgStu = JSON.parse('{"name":"honorZ","age":18,"sex":"male"}');//注意是个字符串,同时里面{}别忘记
console.log(orgStu);
我们以前接触的Java就有面向对象思想。
类:模板
对象:具体的实例
类是对象的抽象,对象是类一个具体表现。
而在JavaScript需要换一下思维方式。
修改原型
原型:_proto_
var student = {
name : "student",
age : 16,
sex : "male",
run : function () {
console.log(this.name + " run.....");
}
};
var xiaoming = {
name : "小明"
};
console.log(xiaoming);
student.run();
// xiaoming.run(); //xiaoming点不出来run
xiaoming.__proto__ = student; //注意这里是两个_下划线
console.log(xiaoming);
xiaoming.run();
修改原型,有点像继承。太随意了,不方便理解。
class继承
class
关键字在ES6引入的,以前版本不支持。
class Student{
constructor(name) {
this.name = name; //属性直接在this.name体现了
};
hello() {
window.alert("Hello");
}
}
var xiaoming = new Student("小明");
xiaoming.hello();
class Pupli extends Student {
constructor(name, grade) {
super(name);
this.name = name;
this.grade = grade;
}
myGrade() {
window.alert(this.grade);
}
}
var xiaogong = new Pupli("小红", 98);
xiaogong.myGrade();
BOM详细解析
图源该博客。
BOM:Browser Object Model浏览器对象模型。
window对象
window 对象,是 JS 的最顶层对象,其他的 BOM 对象都是 window 对象的属性。
//window就是代表浏览器窗口
//可以根据不同的缩放大小获得内外宽高
//还可以进行alert,open一个新网页
navigator对象
window.navigator 对象包含有关访问者浏览器的信息,可以省略window.
// navigator.platform:操作系统类型;
// navigator.userAgent:浏览器设定的User-Agent字符串。
// navigator.appName:浏览器名称;
// navigator.appVersion:浏览器版本;
// navigator.language:浏览器设置的语言;
// userAgent是最常用的属性,用来完成浏览器判断。
screen对象
window.screen 对象包含有关用户屏幕的信息。
location对象(重要)
window.location对象:用于获得当前页面的地址 (URL),并把浏览器重定向到新的页面。在编写时可不使用 window 这个前缀。
location.herf = 'url地址'
hash 返回#号后面的字符串,不包含散列,则返回空字符串。
host 返回服务器名称和端口号
pathname 返回目录和文件名。 /project/test.html
search 返回?号后面的所有值。
port 返回URL中的指定的端口号,如URL中不包含端口号返回空字符串
portocol 返回页面使用的协议。 http:或https:
document对象(十分重要)
document代表当前的页面,HTML DOM文档树。
可以根据id,类,标签定位到特定的位置。就可以实现网页的动态变化,这就是交互。
document.cookie
劫持cookie原理。尽量不要访问恶意的网站,它的js脚本代码可能含有获取你的cookie的恶意代码。
cookie作用,同时打开淘宝和天猫,发现登陆一个,另一个就不需要再登录,自动登录了。清除cookie后,登录信息没了,就都登出了。
所以,我们尽量不要暴漏cookie出去。
同时服务器端这边也在提高安全性,服务器端这边可以设置cookie:readOnly。
history
window.history 对象包含浏览器的历史。
history.back() - 加载历史列表中的前一个 URL。返回上一页。
history.forward() - 加载历史列表中的下一个 URL。返回下一页。 go(“参数”) -1表示上一页,1表示下一页。
DOM:文档对象模型。
浏览器网页就是一个Dom树形结构!
获得DOM节点
var h1 = document.getElementByTagName('h1');//通过标签名得到
var p1 = document.getElementById('p1');//通过id得到
var p2 = document.getElementByClassName('p2');//通过类名得到
更新DOM节点
//操作HTML
var div1 = document.getElementById('div1');
div1.innerText = "123"; /*修改文本的值*/
div1.innerHTML = "123" //会有相关的样式
innerText仅仅修改文本的值
div1.innerHTML = "123"可以解析HTML文本标签
//操作CSS
div1.style.color = 'red';
divElement1.style.fontSize = "20px";
删除DOM节点
删除节点的步骤,先获取父节点,在通过父节点删除自己。
var deleteNode = document.get...;
var father = deleteNode.parentElement;
father.removeChild(deleteNode);
//还可以按下标删除
father.removeChild(father.children[0]);
插入节点
我们获得了某个DOM节点,假设这个DOM节点是空的,我们通过innerHTML就可以增加一个元素,但是如果这个DOM节点有值,我们再修改innerHTML就是覆盖了。
追加。
var a = document.get...
var b = document.get...
b.appendChild(a); //两个已经存在的元素追加
//增加新创建的节点
var newP = document.createElement('p');//创建一个p标签等价于
newP.id = 'newP'; //
newP.innerText = 'Hello,JavaScript';//Hello,JavaScript
var list = document.get...
list.appendChild(newP);
还可以动态增加script标签和link标签,这样就相当于做了个自运行脚本。
/**/
var myScript = document.createElement("script");
myScript.setAttribute('type', 'text/javascript');
操作表单十分重要,关系到验证的问题,直接在这里先进行一些逻辑的判断,就避免去服务器去处理这些基本逻辑。
JQuery库,里面存在大量的JavaScript
//引入在线CDN
//
//https://www.bootcdn.cn/jquery/
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JQuerytitle>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js">script>
head>
<body>
<a href="" id="jqueryTest">点我a>
<script>
$("#jqueryTest").click(function () {
alert("hello");
});
script>
body>
html>
$(selector).action()
鼠标事件,键盘事件
(1)始终记得在js中,相关函数只有带了函数名(),才会执行。仅仅一个函数名,要么是函数声明,要么是函数绑定操作。
(2)$(function (){…})它的设计目的(除其他事项外)是确保一旦页面的所有DOM元素准备就绪即可使用您的函数。仅当DOM加载完成后,只执行一次。