JS笔记
一个页面的组成
HTML 搭建基本的骨架(包含内容或者图片)
css 完善页面的样式(包含动画和特效0
JavaScript(JS)实现人机交互 = 页面中数据的动态绑定
- 操作页面中的DOM(托图片标签 获取元素/更改元素样式/增删改)元素 DOM:document object model(文档对象模型)提供一些属性和方法供我们操作页面的元素
- 操作浏览器browser(利用浏览器的定时器,控制浏览器的关闭、跳转)BOM: browser object model 浏览器操做模型,提供一些属性操作和方法(API)供我们操作浏览器
- 基础操作语法ECMAScript(ES3/5/6~10):JS语言的语法规范
ECMAScript规范
- 1.变量:设定一个名字,用来存储和代表一个具体的值/元素(常量)等
- 常量:不可更改,指的具体的值
- 变量:可以更改,可以让这个名字和其他的值关联,这样它代表的就是其他的值
- 2.数据类型
- 3.基础API方法
- 4.操作语句
…
注意:引用js是在body内引用,引用style是在head内引用
躯体 实际存在的事物 名字 对肉体的命名,我们以后通过名字代表肉体
元素/值 实在的事物 常量 1 起名字 变量
实例
var bodyBox = document.body;
var buttonList = document.getElementsByTagName('button');
buttonList[0].onclick=function(){ bodyBox.style.background = 'red';};
buttonList[1].onclick=function(){ bodyBox.style.background = 'green';};
buttonList[2].onclick=function(){ bodyBox.style.background = 'blue';};
在哪写JS的代码
1.控制浏览器弹出一个警告框
alert(“哥,你真帅啊!!”);
2.让计算机在页面中输出一个内容
document.write()可以向body中输出一个内容
document.write(“看我出不出来~~~”);
3.向控制台输出一个内容
console.log()的作用是向控制台输出一个内容
console.log(“你猜我在哪出来呢?”);
alert("哥,你真帅啊!!");
document.write("看我出不出来~~~");
console.log("你猜我在哪出来呢?");
编写位置
可以将js代码编写到外部js文件中,然后通过script标签引入 写到外部文件中可以在不同的页面中同时引用,也可以利用到浏览器的缓存机制 推荐使用的方式 script标签一旦用于引入外部文件了,就不能在编写代码了,即使编写了浏览器也会忽略 如果需要则可以在创建一个新的script标签用于编写内部代码
<script type="text/javascript" src="js/script.js"></script>
<script type="text/javascript">
alert("我是内部的JS代码");
</script>
<!--
可以将js代码编写到script标签
<script type="text/javascript">
alert("我是script标签中的代码!!");
</script>
-->
基本语法
1.JS中严格区分大小写
2.JS中每一条语句以分号(;)结尾
- 如果不写分号,浏览器会自动添加,但是会消耗一些系统资源,
而且有些时候,浏览器会加错分号,所以在开发中分号必须写
3.JS中会忽略多个空格和换行,所以我们可以利用空格和换行对代码进行格式化
如何起一个名字
- var/function/[let/const/import] xxx = 1
- 命名有规范
- 严格区分大小写 bodyBox BodyBox 两个不同的变量
- 建议采用驼峰命名法 一个复杂的名字由多个词组组成,第一个单词字母小写,其余每一个有意义的首字母大写
- 可以基于 $ _ 大小写字母 数字组成一个名字,数字不能作为开头
x x x 基 于 J Q 选 择 器 获 取 的 内 容 都 存 储 在 以 xxx 基于JQ选择器获取的内容都存储在以 xxx基于JQ选择器获取的内容都存储在以开头命名的变量中
_xxx 下划线开头的一般用于被认为是公共的变量(或者是仅供内部使用的)
以上只是大部分情况是这样的,但是也有一些情况和上述没关系 - 不能使用关键字和保留字
- 关键字就是有特殊含义的
- 保留字未来会成为关键字的
var num; let num; const num;
function sum() {} function声明的变量存储的值是一个函数
import xxx from ‘xxx’;遵循ES6Module模块规范的导入模块
标识符
- 在JS中所有的可以由我们自主命名的都可以称为是标识符
-
例如:变量名、函数名、属性名都属于标识符
-
命名一个标识符时需要遵守如下的规则:
1.标识符中可以含有字母、数字、_、$
2.标识符不能以数字开头
3.标识符不能是ES中的关键字或保留字
4.标识符一般都采用驼峰命名法
- 首字母小写,每个单词的开头字母大写,其余字母小写
helloWorld xxxYyyZzz -
JS底层保存标识符时实际上是采用的Unicode编码,
所以理论上讲,所有的utf-8中含有的内容都可以作为标识符
-
用变量可以存储哪些值? JS中的数据类型分类?
基本数据类型/值{原始值}类型
数字 number
- 数字:0 -1 1 0.1 NaN Infinity
- NaN:not a number不是一个有效数字,但是属于number数据类型
- Infinity:无穷大的值 -Infinity无穷小的值
var num = 1;
num = 2;
- =赋值 ==比较
NaN==NaN false不相等 NaN和任何值都不想等 无法基于xxx==NaN 来验证xxx是否为有效数字,我们应该基于一个新方法来验证
isNaN{[value]}
- 如果[value]值不是数字类型,默认需要先转化为数字类型,然后再去验证是否为有效数字
- 如果是有效数字,返回false,如果不是有效数字,返回true
字符串 string
- 字符串:只要用``(飘号,Tab上面的键) ‘’(单引号) “”(双引号) 包起来的都是字符串’zhufeng’ '0 ’ ‘function sum(){}’
- 每个字符串都由多个字符组成
布尔 boolean
布尔:true真 false假
空 null
空值:null
未定义 undefined
未定义:undefined
唯一值 symbol
大整型 bigint
引用数据类型
对象类型
普通对象 {xxx:‘xxx’}
- 每个对象都是一个复杂的数据结构,包含很多描述自己的属性,而对象诞生的目的就是为了把描述同一个事物的属性(键值对)放在一起,以此来解决多个对象中描述冲突的问题
- 键值对:属性名和属性值
- 操作对象中的每个成员
- 对象的每个成员可以是数字、字符串、
- 获取成员
- 对象.成员 person1.name
- 上述方案不适用于数字方案 (会报语法错误Uncaught SyntaxError: missing ) after argument list)
- 对象[成员] person[1] person[‘name’]
- 如果对象中没有这个成员,值就是undefined
- 新增或修改成员的值
- 一个对象的成员不能重复,如果重复,以最后的值为主
- 当我们去修改成员的值的时候,如果成员存在,则修改值,如果成员不存在,则设置一个新的值
- 删除对象的某个成员
- 假删除:把成员值修改为null/undefined即可
- person1.age = null;假删除后显示age:null;
- 真删除:彻底删掉(delete 对象[成员])
- delete person1.age;删除完后无age这个成员
- 假删除:把成员值修改为null/undefined即可
person1.name = '东子';//修改成员的值 person['name'] = 'xxx'
person1.teacher = '周老师';//新增成员 person1.teacher = 'xxx';
var name = "紫东";
var age = 81;
var height = '150cm';
var hobby = '女孩子';
var name = '刘颖';
var age = 12;
var height = '150cm';
var hobby = '女孩子';
var name = '刘颖';
var age = 12;
var height = '178cm';
var hobby = '读书'
//console.log{[value]}在控制台输出value值
//F12/FN+F12 打开控制台=>Console
console.log(name);覆盖了之前那个紫东
// 函数:函数名+形参+函数体+执行+实参
对以上的改良
var person1 = {
name:'紫东',
age: 81
};
var person2 = {
name:'刘颖',
age:12
};
console.log(person1.age);
console.log(person2.name);
数组对象 [10,20]
- 由0-多组键值对构成(他也是对象):
- 我们无需写属性名(写的时候,写的是属性值),属性名默认是数字,而且数字以0开始,逐渐递增,我们把代表当前是数组中第几的数字属性名称为“索引”;所以数组类型就是以数字为索引,逐级递增的数据结构
- 默认由一个length的属性,存储的是数组的长度
var arr = [10,20,30];
//获取整个数组
console.log(arr);
//获取数组长度、
console.log(arr.length);
//获取数组第二项
console.log(arr[1]);
- 正则对象 /^\d+$/
- 日期对象 Thu Mar 11 2021 16:00:17 GMT+0800 (中国标准时间)
- 函数类型
数据类型检测
- 基于一些方法检测当前值的类型
- typeof [value]
- instanceof
- constructor
- Object.prototype.toString.call{[value]}
typeof 要检测的数据 - 检测结果是一个字符串,字符串中包含了所属类型的字符,例如:“number“/“string”/“boolean”/“undefined”/“function”/“object”/
- typeof null =>“object” 因为所有制在计算机中都是二进制存储的,null存储的是000,而typeof底层检测机制是按照2进制来检测的,并且认为以000开头的都是对象,这样导致了没有的bug
这里是引用
-
- typeof检测对象返回都是”object“,没有办法区分是普通对象还是其他对象
数据类型转换
把某些数据类型转化为指定类型
- 1.把其他数据类型转化为number类型
-
手动转换
- parseInt/parseFloat
- Number([value])
-
隐式转换(自己默认转换的)==>采用的就是namber([value])这个规则
-
isNaN([value])如果[value]不是数字则先转换为数字,再进行有效数字的检测
-
数学运算 加减乘除及取余数等(注意在加法运算中遇到字符串、对象,则进行的不是加法运算而是字符串拼接)
-
-
在两个等于号比较的时候如果两边值不一样,大部分下都是转换为数字进行比较的
-
。。。。
-
-
Number([value]):把其他数据类型转化为number类型
- 把字符串转换为数字类型:空字符串变为零,只要字符串中出现任意一个非有效数字字符,结果都是NaN
- 把布尔转换为数字:true变1,false变0
- null变为数字0
- undefined变为NaN
- symbol不能基于Number转换为数字:Uncaught TypeError
- bigint是正常转换的
- 把引用数据类型(对象 /函数)转换为数字:先把对象值转换为字符串(对象.toString() 特殊:其实是先基于valueOf获取他的原始值),然后再把字符串转化为数字
- 普通对象转换成字符串之后结果都是[object Object]
- 函数转化为字符串结果是”函数看到的那些代码“
- 数组转化为字符串 空数组变为空字符串,剩下的是把数组中的每一项基于逗号”,“分隔(只有一项时不分隔)
{{0:0}}toString
VM94:1 Uncaught SyntaxError: Unexpected token ':'
{{0:0}}toString();
VM113:1 Uncaught SyntaxError: Unexpected token ':'
({0:0}).toString()
"[object Object]"
function fn(){console.log('ok')}
undefined
fn.toString{}
VM241:1 Uncaught SyntaxError: Unexpected token '{'
fn
ƒ fn(){console.log('ok')}
fn.toString{}
VM279:1 Uncaught SyntaxError: Unexpected token '{'
fn.toString()
"function fn(){console.log('ok')}"
[].toString
ƒ toString() { [native code] }
['10'].toString
ƒ toString() { [native code] }
['10'].toString()
"10"
[].toString()
""
加法运算的规则
- 两边只要有对象或者字符串就会进行字符串拼接
- “+字符串” 或者”++字符串“再或者”字符串++“,这种情况也是把字符串转化为数字
var n=“10”;
console.log(1+n);//“110”
console.log(+n);//10
console.log(++n);//11
1+‘2’//‘12’ 1+[10]//把对象先转化为字符串,结果是字符串拼接11
1+true+null+undefined+‘zhufeng’+false+[10]+undefined
//NaNzhufeng10undefined
parseInt/parseFloat([value]):他的规则和number完全不一样
他的规则:线把value变成字符串,然后从左往右开始查找,找到所有的有效字字符,遇到一个非有效数字则直接停止不管后面还有没有=有效数字
注:parseInt比parseFloat少识别一个小数点”.“
2.比其它类型转换为字符串
- 手动转换
- 手动转换
- [value].toString()
- String([value])
- 隐式转换
特殊:普通对象转换为字符串结果是”[object Object]“
3.把其他类型转化为布尔类型
- 手动转化
- Boolean([value])
- ! 先转换为布尔类型,然后取反
- !! 取反再取反,相当于没有取反,则只是转换为布尔类型
- 隐式转化
- 条件判断中,总要判断出真假
- ·········
规则:只有”0/NaN/null/undefined/空字符串“ 五个值变为false
三元运算符
在JS中我们会存在一些逻辑判断
- if 、else、else if
- 三元运算符
- switch case
三元运算符的语法:
- 条件?条件成立做的事情:条件不成立做的事情
// 先计算 {} + 0 是真是假:=>
如果大括号在前浏览器会认为除了他是个大括号,他还可能是一个代码块,因此不让其参加运算,计算的只有+0 //
如果想让其作为对象参与运算,则基于”小括号“包裹他即可:{{}+0} {} + 0 ? alert(‘ok’) : alert(‘no’);
// 先计算”0+{}“ 是真的还是假的:=> 结果”0[object Object]“ =>代表真 0 + {} ?
alert(‘ok’) : alert(‘no’);
if 、else、else if
if(条件一){
条件一成立干的事
}else if(条件二){
条件而成立做的事情
}。。。。。
else{
以哦上都不成立做的事情
}
单独用
if(条件){。。。}
if(条件){。。。。}else{。。。。}
if(1){...}把值转换为布尔判断真假
if(n==10){} 正常条件 == / === / >= / < =/</>
if(n == 1|| m==2){} 多条件 || 或者(一个为真,整体为真) &&并且(都为真,整体才是真)
if(n==1&&m==2){}
问题1:关键字和保留字
关键字”就是 JS
本身已经使用了,具有一定特殊的含义,你就不能再用它们充当变量名啊方法名啊什么的。包括(按字母排序):break、case、catch、continue、default、delete、do、else、finally、for、function、if、in、instanceof、new、return、switch、this、throw、try、typeof、var、void、while、with
等。
“保留字”实际上就是预留的“关键字”,意思是现在虽然现在还不是关键字(也就是本身还不具备特殊含义的),但是未来可能会成为关键字的,你一样是不能使用它们当变量名啊方法名的。包括(按字母排序):abstract、boolean、byte、char、class、const、debugger、double、enum、export、extends、fimal、float、goto、implements、import、int、interface、long、mative、package、private、protected、public、short、static、super、synchronized、throws、transient、volatile
等。
问题2:浏览器输出的常见方案 alert/confirm/prompt/console.xxx
1.浏览器窗口弹窗 alert/confirm/prompt //都是要把输出的内容先转换为字符串再输出都是弹窗模式(都会阻碍GUI渲染线程的渲染)
①alert 是消息提示框 只有一个确定键
alert (1)=>字符串1
alert({xxx:‘xxx’});=>[object Object]
②confirm是确认提示框 有确定、取消 两个键
我们可以设置一个变量来接受用户的选择
var flag = confirm(‘hhh’);
console.log(flag);
③prompt在confirm的基础上可以输入内容
var text = prompt(‘哈哈哈’);
console.log(text);//点击取消获取结果为null 点击确定会把用户输入的内容获取到”“/”…“
2.控制台输出
原始什么数据类型就输出什么数据类型
不阻碍GUI渲染
console.log([value])
console.log([value1],[value2],)
console.dir([value])输出详细信息,主要针对的是对象值
console.table([value])把一个json对象格式的数据以表格方式输出
var bodyBox = document.body;
console.log(bodyBox);
console.dir(bodyBox);
var json = [{
id: 1,
name: ‘珠峰培训’,
age: 11
},{
id: 2,
name: ‘侯老师’,
age: 30
}];
console.table(json);
3.document.write{[value]}//把内容先转换为字符串,然后写在页面中
//document.write(“hhhhhhh”);4.innerHTML/innerText
向页面指定的元素中写入内容
区别:html可以识别html标签 text无法识别
value是专门给表单元素设置内容的
document.body.innerHTML = “中华人民共和国”;
document.body.innerText = “中华人民共和国”;
value
问题3:分析obj[name]和obj[‘name’]的区别
//此时的name是一个变量(名字,变量名):代表存储的”1“ var name = ‘1’;
//一个对象是由零个到多个属性名j和属性值组成的,此处的name是属性名(和变量不是一个东西)
//对象的属性名可以是字符串或者数字
name属性名其实就是”name“ 1.属性名其实就是1/“1” var obj = { name:“zhufeng”, age: 11, 1:100 };
//获取对象的某个成员值
// obj.成员 obj.name
// obj[成员] obj[“name”]
obj[‘name’] 再获取其属性名为”name“的成员值console.log(name);
//=>1 console.log(obj[‘name’]);
//=>zhufeng
问题4:typeof typeof typeof[10,20]
var result = typeof typeof typeof[10,20];
console.log(result);
typeof[10,20];=>object
typeof “object”;=>“string”
因为typeof检测的结果优先是字符串,所以第二次检测,不论什么情况,再检测出来的结果都是”string“。。。出现两个及两个以上tytpeof检测结果都是”string“
console.log(result);//“string”
对象
JS中数据类型
- String 字符串
- Number 数值
- Boolean 布尔值
- Null 空值
- Undefined 未定义
- 以上这五种类型属于基本数据类型,以后我们看到的值
只要不是上边的5种,全都是对象
- 以上这五种类型属于基本数据类型,以后我们看到的值
- Object 对象
基本数据类型都是单一的值"hello" 123 true,
值和值之间没有任何的联系。
在JS中来表示一个人的信息(name gender age):
var name = “孙悟空”;
var gender = “男”;
var age = 18;
如果使用基本数据类型的数据,我们所创建的变量都是独立,不能成为一个整体。
对象属于一种复合的数据类型,在对象中可以保存多个不同数据类型的属性。
对象的分类:
1.内建对象
- 由ES标准中定义的对象,在任何的ES的实现中都可以使用
- 比如:Math String Number Boolean Function Object…
2.宿主对象
- 由JS的运行环境提供的对象,目前来讲主要指由浏览器提供的对象
- 比如 BOM DOM
3.自定义对象
- 由开发人员自己创建的对象
创建对象
使用new关键字调用的函数,是构造函数constructor
构造函数是专门用来创建对象的函数
使用typeof检查一个对象时,会返回object
//创建对象
/*
* 使用new关键字调用的函数,是构造函数constructor
* 构造函数是专门用来创建对象的函数
* 使用typeof检查一个对象时,会返回object
*/
var obj = new Object();
/*
* 在对象中保存的值称为属性
* 向对象添加属性
* 语法:对象.属性名 = 属性值;
*/
//向obj中添加一个name属性
obj.name = "孙悟空";
//向obj中添加一个gender属性
obj.gender = "男";
//向obj中添加一个age属性
obj.age = 18;
/*
* 读取对象中的属性
* 语法:对象.属性名
*
* 如果读取对象中没有的属性,不会报错而是会返回undefined
*/
//console.log(obj.gender);
//console.log(obj.hello);
/*
* 修改对象的属性值
* 语法:对象.属性名 = 新值
*/
obj.name = "tom";
/*
* 删除对象的属性
* 语法:delete 对象.属性名
*/
delete obj.name;
console.log(obj.age);
向对象中添加属性
属性名:
-
对象的属性名不强制要求遵守标识符的规范
什么乱七八糟的名字都可以使用 -
但是我们使用是还是尽量按照标识符的规范去做
-
如果要使用特殊的属性名,不能采用.的方式来操作
需要使用另一种方式:
语法:对象[“属性名”] = 属性值
读取时也需要采用这种方式使用[]这种形式去操作属性,更加的灵活,
在[]中可以直接传递一个变量,这样变量值是多少就会读取那个属性
var obj = new Object();
/*
* 向对象中添加属性
* 属性名:
* - 对象的属性名不强制要求遵守标识符的规范
* 什么乱七八糟的名字都可以使用
* - 但是我们使用是还是尽量按照标识符的规范去做
*
*/
obj.name = "孙悟空";
//obj.var = "hello";
/*
* 如果要使用特殊的属性名,不能采用.的方式来操作
* 需要使用另一种方式:
* 语法:对象["属性名"] = 属性值
* 读取时也需要采用这种方式
*
* 使用[]这种形式去操作属性,更加的灵活,
* 在[]中可以直接传递一个变量,这样变量值是多少就会读取那个属性
*
*/
obj["123"] = 789;
obj["nihao"] = "你好";
var n = "nihao";
//console.log(obj["123"]);
/*
* 属性值
* JS对象的属性值,可以是任意的数据类型
* 甚至也可以是一个对象
*/
obj.test = true;
obj.test = null;
obj.test = undefined;
//创建一个对象
var obj2 = new Object();
obj2.name = "猪八戒";
//将obj2设置为obj的属性
obj.test = obj2;
//console.log(obj.test.name);
/*
* in 运算符
* - 通过该运算符可以检查一个对象中是否含有指定的属性
* 如果有则返回true,没有则返回false
* - 语法:
* "属性名" in 对象
*/
//console.log(obj.test2);
//检查obj中是否含有test2属性
//console.log("test2" in obj);
//console.log("test" in obj);
console.log("name" in obj);
基本数据类型
String Number Boolean Null Undefined
引用数据类型
Object
JS中的变量都是保存到栈内存中的,
基本数据类型的值直接在栈内存中存储,
值与值之间是独立存在,修改一个变量不会影响其他的变量
对象是保存到堆内存中的,每创建一个新的对象,就会在堆内存中开辟出一个新的空间,
而变量保存的是对象的内存地址(对象的引用),如果两个变量保存的是同一个对象引用,
当一个通过一个变量修改属性时,另一个也会受到影响
var a = 123;
var b = a;
a++;
/*console.log("a = "+a);
console.log("b = "+b);*/
var obj = new Object();
obj.name = "孙悟空";
var obj2 = obj;
//修改obj的name属性
obj.name = "猪八戒";
/*console.log(obj.name);
console.log(obj2.name);*/
//设置obj2为null
obj2 = null;
/*console.log(obj);
console.log(obj2);*/
var c = 10;
var d = 10;
//console.log(c == d);
var obj3 = new Object();
var obj4 = new Object();
obj3.name = "沙和尚";
obj4.name = "沙和尚";
/*console.log(obj3);
console.log(obj4);*/
/*
* 当比较两个基本数据类型的值时,就是比较值。
* 而比较两个引用数据类型时,它是比较的对象的内存地址,
* 如果两个对象是一摸一样的,但是地址不同,它也会返回false
*/
console.log(obj3 == obj4);
对象字面量
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript">
//创建一个对象
//var obj = new Object();
/*
* 使用对象字面量来创建一个对象
*/
var obj = {};
//console.log(typeof obj);
obj.name = "孙悟空";
//console.log(obj.name);
/*
* 使用对象字面量,可以在创建对象时,直接指定对象中的属性
* 语法:{属性名:属性值,属性名:属性值....}
* 对象字面量的属性名可以加引号也可以不加,建议不加,
* 如果要使用一些特殊的名字,则必须加引号
*
* 属性名和属性值是一组一组的名值对结构,
* 名和值之间使用:连接,多个名值对之间使用,隔开
* 如果一个属性之后没有其他的属性了,就不要写,
*/
var obj2 = {
name:"猪八戒",
age:13,
gender:"男",
test:{name:"沙僧"}
};
console.log(obj2.test);
</script>
</head>
<body>
</body>
</html>