导学:
question1 能够说出javaScript是什么
question2 能够知道javaScript的发展历史
question3 能够说出浏览器执行javaScript的原理
question4 能够说出javaScript由哪三部分组成
question5 能够写出javaScript三个输入输出语句
question3 浏览器如何执行js?
浏览器分为两部分:渲染引擎和js引擎
浏览器本身不会执行js代码,而是通过内置javaScript引擎来执行。
question4 js组成
js由js语法和dom(api文档)和bom(浏览器模型)三部分组成
js一般的书写方式:
写在<script> </script>标签内,有三种置放方式,要不然放在<head></head>标签内,要不然放在<body></body>标签内,要不然外部js文件。
书写格式如下:
方式一:
<html>
<body>
<script src="myScript.js">
</script>
</body>
</html>
然后您再新建一个文本编辑文件
命名为maScript.js
里面不用再写标签,直接写您想写的js代码即可。
方式二:
(较为常见,一般写在<head></head>标签内
基础概念 变量
、
基础概念 数据类型
以下为一些杂碎的tips:
string类型加单引号或双引号都可
一个小练习 弹出网页警示框
<html>
<meta charset="UTF-8">
<head>
<title>document</title>
<script>
alert('sssssa,aasd:"staff"');
</script>
<body>
</body>
</html>
字符串的拼接
如果您想用带变量进来拼接
您可以这么写
<script>
var age=18;
console.log('pink'+age+'岁');
</script>
而不要这样写
<script>
var age =18;
console.log('pinkage岁');
</script>
这样是赋值不过来的
下面我们做一个案例
案例1 显示年龄
需求:弹出一个输入框,需要用户输入年龄,之后弹出一个警示框显示“您今年xx岁啦“
这是我写的代码:
<html>
<meta charset="UTF-8">
<head>
<title>document</title>
<script>
var age=21;
alert('您今年'+age+'岁了“);
</script>
<body>
</body>
</html>
正确的代码应该是
<html>
<meta charset="UTF-8">
<head>
<title>document</title>
<script>
var age=prompt("请输入您的年龄");
var str='您今年已经'+age+'岁了';
alert(str);
</script>
<body>
</body>
</html>
typeof获取检测变量的数据类型
基础概念 字面量
基础概念 数据类型转换
转换成字符串类型
不同的数据类型相互转换,一般会有三种方式的转换
代码:
显示结果如下图所示
转换成数字类型
代码如下:
案例2 计算年龄
此案例要求在页面中弹出一个输入框,我们输入出生年份后,能计算出我们的年龄。
思路:首先弹出一个询问框,然后一个变量,再然后弹出警示框。
<html>
<meta charset="UTF-8">
<head>
<title>document</title>
<script>
var year=prompt("请输入您的出生年份");
var age=2021-year
var str='您今年已经'+age+'岁了';
alert(str);
</script>
<body>
</body>
</html>
案例3 简单加法器
计算两个数的值,用户输入第一个值后,继续弹出第二个输入框并输入第二个值,最后通过弹出窗口显示出两次输入值相加的结果
我写的代码:
<html>
<meta charset="UTF-8">
<head>
<title>document</title>
<script>
var page1=prompt("请输入第一个数");
var page2=prompt("请输入第二个数");
var age=page1+page2;
var str='两数相加的结果为:'+age;
alert(str);
</script>
<body>
</body>
</html>
结果报错了,相加结果都不对没有两两相加而是想字符串类型相加了,因为二者数据类型需要转换。
正确代码如下
<html>
<meta charset="UTF-8">
<head>
<title>document</title>
<script>
var num1=prompt("请输入第一个数");
var num2=prompt("请输入第二个数");
var result=parseFloat(num1)+parseFloat(num2);
alert('两数相加的结果是:'+result);
</script>
<body>
</body>
</html>
您也可以这样写:
<script>
var num1=parseFloat(prompt(""));
var num2=parseFloat(prompt(""));
var result=num1+num2;
alert('两数相加的结果是:'+result);
</script>
转换成布尔型
课后作业(2道题)
1、给同桌讲讲交换两个变量的值 如何做
2、一次询问并获取用户的姓名、年龄、性别,并且打印用户信息图
<html>
<meta charset="UTF-8">
<head>
<title>document</title>
<script>
var info1=prompt("请输入您的姓名");
var info2=prompt("请输入您的年龄");
var info3=prompt("请输入您的性别");
var result=info1.toString()+info2.toString()+info3.toString();
alert('您的姓名是:'+info1\n'您的年龄是:'+info2\n+'您的性别是:'+info3);
</script>
<body>
</body>
</html>
正确代码:
<html>
<meta charset="UTF-8">
<head>
<title>document</title>
<script>
var name=prompt("请输入您的姓名");
var age=prompt("请输入您的年龄");
var sex=prompt("请输入您的性别");
alert('您的姓名是:'+name+'\n'+'您的年龄是:'+age+'\n'+'您的性别是:'+sex);
</script>
<body>
</body>
</html>
案例6 求学生成绩
要求用户输入班级人数人数后,之后一次输入每个学生的成绩,最后打印出该班级的总成绩已经平均成绩
代码:
<html>
<meta charset="UTF-8">
<head>
<title>document</title>
<script>
var num=prompt("请输入班级总人数:");
var sum=0;//求和的变量
var average=0;//求平均值的变量
for(var i=1;i<=num;i++){
var score=prompt('请您输入第'+i+'个学生成绩');
//因为从prompt=取过来的数据是字符串型的需要转换为数字型
sum=sum+parseFloat(score);
}
average=sum/num;
alert('班级总成绩是:'+sum);
alert('班级平均分是:'+average);
</script>
<body>
</body>
</html>
javaScript输出
javaScript可以通过不同的方式来输出数据
- 使用 window.alert() 弹出警告框。
- 使用 document.write() 方法将内容写到 HTML 文档中。
- 使用 innerHTML 写入到 HTML 元素。
- 使用 console.log() 写入到浏览器的控制台。
window.alert()
<html>
<meta charset="UTF-8">
<head>
<title>OK</title>
</head>
<body>
<h1>我的网页<h1>
<p>我的第一个段落</p>
<script>
window.alert(5+6);
</script>
</body>
</html>
显示结果
document.write()
<html>
<meta charset="UTF-8">
<head>
<title>OK</title>
</head>
<body>
<h1>我的网页<h1>
<p id="demo">我的第一个段落</p>
<script>
document.getElementById("demo").innerHTML="嘿嘿这个元素被我改变了";
</script>
</body>
</html>
显示结果
JavaScript代码块
js可以分批组合起来
<html>
<meta charset="UTF-8">
<head>
<title>OK</title>
</head>
<body>
<h1>我的网页<h1>
<p id="demo">我的第一个段落</p>
<script>
function myFunction(){
document.getElementById("demo").innerHTML="你好世界!";
}
</script>
<p>
<button type="button" οnclick="myFunction()">点我</button>
</p>
<p>当您点击上面的按钮时,demo元素的内容会被改变</p>
</body>
</html>
p15 运算符
1、“+”
2、“-”
3、“*”
4、“/”
5、“%”
如果运算值中有string类型,那么非string类型会转化成string型与其相加,但要注意运算顺序
任何值与NAN(非number类型)运算都是NAN
p16 一元运算符(只需要一位操作数)
示例代码1: 示例代码2:
var a=123; var a=123;
a=+a a=-a;
console.log("a="+a); console.log("a="+a);
//"a=123" //"a=-123"
正号不会对数字产生什么影响 负号可对数字进行取反
对于非Number类型的值,它会将其先转换为number,然后再运算
var result=1++"2"+3; //16
这属于一种隐式的类型转换
p17自增和自减
自增:给自己增加值
a=a+1; 但一般我们不这么写
我们写成a++
您也可以写成++a
二者都会使原变量的值自增1,但二者不同的是,++a的值等于原变量的新值(自增后的值)
而a++呢,还是等于原变量的值。
自减同理
num--是变量原值,--num是变量新值
p19 逻辑运算符
!非
&&与
|| 或
p21 赋值运算符
"=" "+=" "-=" "*=" "/=" "%="
p22 关系运算符
">" "<" "=" ">=" "<="
tips:比较两个string类型的数值时,一定要类型转换
console.log(5>"11"); (x)
console.log(5>+"11"); (v)
任何值与NAN(非Number类型做比较都是false)
代码示例:
console.log(1>true); //false
console.log(1>"0"); //true
console.log(10>null); //true
//如果比较对象二者都是字符串,则不是比较数值大小,而是去比较二者的unicode编码
console.log("11"<"5"); //true
p23 unicode编码表
这张表收录了大量的文字、字符、数字,并且有相应的编码,倘若你想在网页中显示,在js中你可以这样用
<script type="text/Javascript">
console.log("\u2620");
</script>
如果你想在网页页面上显示,则您需要写在<body></body>标签内
写在<head>标签内的那是十六进制,而在网页中您需要10进制的编码。所以您可以使用计算器算一个换算过来 2620是9760
<body>
<h1 style="font-size:100px;">☠<h1>
</body>
p-24 相等运算符
!= 不相等
== 相等 会做不同类型的类型转换
console.log("123"=123);//true
=== 全等 不会做数据类型转换
!== 不全等,也不会自动做数据类型转换
p25 条件运算符
条件运算符也叫三元运算符(即三个数)
语法
条件表达式?语句1:语句2
var a=30;
var b=40;
var max=a>b?a:b
if语句例子试写
<html>
<head>
<meta charset="UTF-8">
<script type="text/javascript">
var height=prompt("请输入你的身高:");
var weight=prompt("请输入你的体重:");
var money=prompt("请输入你的财富:");
if(height>180 && money>1000 && weight<150){
alert("我一定要嫁给他!");
}else if(height>180 || money>1000 || weight<150){
alert("嫁吧,比上不足,比下有余!");
}
else{
alert("不嫁.");
}
</script>
</head>
<body>
</body>
</html>
if语句练习2 比较三个数的大小,并且按照大小顺序进行输出
//prompt()函数的返回值都是String类型
所以需要用到“+”号来进行数据类型的转换
<html>
<head>
<meta charset="utf-8">
<script>
var num1= +prompt("请输入第一个数:");
var num2= +prompt("请输入第二个数:");
var num3= +prompt("请输入第三个数:");
if(num1<num2&&num1<num3){
if(num2<num3){
alert(num1+","+num2+","+num3);
}else{
alert(num1+","+num3+","+num2);
}
}else if(num2<num1&&num2<num3){
if(num1<num3){
alert(num2+","+num1+","+num3);
}else{
alert(num2+","+num3+","+num1);
}
}else{
if(num1<num2){
alert(num3+","+num1+","+num2);
}else{
alert(num3+num2+","+num1);
}
}
</script>
</head>
<body>
</body>
</html>
案例3 转换为Boolean值
<html>
<head>
<meta charset="utf-8">
<script>
var num=20;
if(num=10){
alert("hahaha");
}
console.log(num=1);
</script>
</head>
<body>
</body>
</html>
switch语句 (条件分支语句也叫switch语句)
语法:
switch(条件表达式) {
case 表达式:
语句...
break;
case 表达式:
语句...
break;
default:
语句...
break;
}
例
num=1;
switch(num){
case1:
console.log("aa");
break;
case2:
console.log("bb");
break;
case3:
console.log("cc");
break;
default:
console.log("wrong");
break;
}
因为num变量为1,所以console控制输出aa
switch语句和if语句的功能实际上是有重复的,可以根据自己的习惯
switch小练习
1、score/10=9.9(score=99)用parseInt()将浮点数转换成int型数据。
<html>
<head>
<meta charset='UTF-8'>
<script>
var score=prompt("请输入成绩:");
var num=score/10;
parseInt(num);
switch (num){
case 10:
case 9:
case 8:
case 7:
case 6:
alert("here");
break;
default:
alert("pass");
break;
}
</script>
</head>
<body>
</body>
</html>
while循环语句
while循环语法:
while(条件表达式 ){
语句...
}
例子:
<html>
<head>
<meta charset='UTF-8'>
<script>
var n =1;
while(true){
alert(n++);
if(n==10){
break;
}
}
</script>
</head>
<body>
</body>
</html>
例2
<html>
<head>
<meta charset='UTF-8'>
<script>
//创建一个循环,往往需要三个步骤
//1、创初始化一个变量
var i=6;
//2、在循环中设置一个条件表达式
while(i<=10){
//3、定义一个更新表达式,每次更新初始化变量
document.write(i++ +"<br />");
}
</script>
</head>
<body>
</body>
</html>
do...while循环语法:
do{
语句
}while(条件表达式)
do...while语句在执行时,会先执行循环体,循环体执行完毕之后,再对while后的条件表达式进行判断
向页面中输入数据的写法:
document.write(1);
<html>
<head>
<meta charset='UTF-8'>
<script>
var i=6;
do{
document.write(i++ +"<br />");
}while(i<=16);
</script>
</head>
<body>
</body>
</html>
这样结果就会从1一直输出到16
while练习
还是求小明成绩的练习
<html>
<head>
<meta charset='UTF-8'>
<script>
while(true){
var score=prompt("请输入小明的期末成绩:");
if(score>=0&&score<=100){
break;
}
alert("请输入有效的分数");
}
if (score > 100 || score < 0 || isNaN(score)) {
alert("拉出去毙了~~~");
} else {
//根据score的值来决定给小明什么奖励
if (score == 100) {
//奖励一台宝马
alert("宝马,拿去~~~");
} else if (score >= 80) {
//奖励一个手机
alert("手机,拿去玩~~~");
} else if (score >= 60) {
//奖励一本参考书
alert("参考书,拿去看~~~");
} else {
alert("棍子一根~~");
}
}
</script>
</head>
<body>
</body>
</html>
for循环
案例1 打印1-100之间所有奇数之和
<html>
<head>
<meta charset='UTF-8'>
<script>
//创建一个变量,用来保存奇数之和
var num=0;
//打印1-100之间的数
for(var i=1,sum=0;i<=100;i++){
//判断i是否为奇数
//不能被2整除的数就是技术
if(i %2 !=0){
sum=sum+i ;
}
}
console.log("奇数之和:"+sum);
alert(sum);
</script>
</head>
<body>
</body>
</html>
for循环2
打印1-100之间所有7的倍数的个数
<html>
<head>
<meta charset='utf-8'>
<script>
var sum=0;
var count=0;
for(var i=1;i<=100;i++){
//
if(i%7==0){
//判断i是否为7的倍数
sum+=i;
//使计数器自增1
count++;
}
}
alert("总和为"+sum);//输出总和
alert("总数量为"+count);//输出总数
</script>
</head>
</html>
总和为735
总数量为14
案例3 水仙花数
水仙花是指一个3位数,每一位的数字的立方相加等于它本身
比如1^3+5^3+3^3=153,请打印所有的水仙花数
<html>
<head>
<meta charset='utf-8'>
<script>
for(var i=100;i<1000;i++){
//获取i的百位 十位 个位的数字
//获取百位数字
var ge=parseInt(i%10);
var shi=parseInt(i/10%10);
var bai=parseInt(i/10/10%10);
if(ge*ge*ge+shi*shi*shi+bai*bai*bai==i){
document.write(i);
}
}
</script>
</head>
</html>
质数练习
随机输入一个数,判断它是否为质数
质数:只能被1和它自身整除的数,1不是质数也不是合数,质数必须是大于1的自然数
<html>
<head>
<meta charset="utf-8">
<script>
var num=prompt("请输入一个大于1的整数:");
if(num<=1){
alert("该值不合法。");
}else{
//
//
var flag=true;
//
//
for(var i=2;i<num;i++){
if(num%i==0){
//
//
flag=false;
}
}
if(flag){
alert(num+"是质数");
}else{
alert("这不是质数");
}
}
</script>
<body>
</body>
</html>
嵌套for循环
 表示1个空格
<html>
<head>
<meta charset="utf-8">
<script>
//var i用来控制图形的高度是多少
for(var i=0;i<5;i++){
//内嵌一个循环控制图形的宽度
for(var j=0;j<i+1;j++){
document.write("* ");
}
document.write("<br />");
}
</script>
</head>
<body>
</body>
</html>
打印结果如下:
如果您想把这个图形反过来
嵌套循环2 打印九九乘法表
<html>
<head>
<meta charset="utf-8">
<script>
//i用来创建外层循环,用来控制乘法表的高度
for(var i=1;i<9;i++){
//内嵌一个循环控制图形的宽度
for(var j=1;j<=i;j++){
document.write("<span>"+j+"*"+i+ "="+i *j+"</span>");
}
document.write("<br />");
}
</script>
<style type="text/css">
body{
width:2000px;
backgroud-color:#87CEEB;
}
span{
display:inline-block;
width:80px;
background-color:#FCD410;
}
</style>
</head>
<body>
</body>
</html>
嵌套循环练习2 :打印楚1-100之间所有的质数
质数:能被自己整除的数字,不为1。自然数
break关键字
break用来退出switch或循环语句,不能在if语句中使用
break关键字,会立即终止离它最近的那个循环语句。
但是如果您想break终止指定位置的语句,您用到label循环语句
语法:
label:循环语句
例如 我取名为outer
outer:
for(var i=0;i<5;i++){
console.log("ss"+i)
for(var j=0;j<5;j++){
break outer;
console.log(“ee"+j);
}
}
此时执行到break时候,会终止outer下的这个外层循环。(即整体循环全部结束)
continue关键字
continue关键字可以用来跳过当次循环,同样continue也是默认只会对离它最近的循环循环起作用。
比如
for(var i=0;i<3;i++){
if(i==2){
continue;
}
console.log(i);
}
打印台会输出0、1、3 而会跳过2
因为continue是跳过当次循环,然后label方法在这里和在break时候的用法一样
计时器console.time() console.timeEnd()
因为我们得优化代码运行速度,所以在这里会用到计时器
console.time("test");
运行语句
console.timeEnd(“test ”);
示例代码:
<html>
<head>
<meta charset="utf-8">
<script>
console.time("test");
//var i用来控制图形的高度是多少
for(var i=0;i<5;i++){
//内嵌一个循环控制图形的宽度
for(var j=0;j<i+1;j++){
document.write("* ");
}
document.write("<br />");
}
console.timeEnd("test");
</script>
</head>
<body>
</body>
</html>
p46 对象的简介
对象是一种复合的数据类型 object
对象的分类
1、内建对象(string Math Function Oobject)
2、宿主对象
由js的运行环境提供的对象,目前主要是值浏览器提供的对象,比如bom和dom
例如
console.log( );
document.write( );
console和document这俩指的就是宿主对象
对象的基础操作
1、创建对象 使用new关键字调用的函数,是构造函数constructor
var obj =new Object;
2、往对象里添加的值,叫“属性”
obj.name="小明";
3、读取对象中的属性
语法:
console.log(obj.gender);
修改对象的属性值obj.name="ton";
删除属性 delete obj.name;
如果查找对象里没有的属性,会返回undefined
p48 属性名与属性值
tips 如果您要用特殊字符取名 例如123,不能用"."的方式来操作
得用[]这种形式去操作属性,会更加灵活,崽括号中可以直接穿一个变量,这样变量值是多少,就会读取哪个属性
obj["123"]=789;
console.log["123"];
var n="nihao";
obj["nihao"]="你好";
console.log(obj[n]);
//输出“你好”
检查一个对象是否含有指定的属性
console.log("test2" in obj); //false
p49 基本数据类型和引用数据类型
p50 对象字面量
我们一般这样创建对象
var obj1=new Object();
console.log(typeof obj1); //object
//使用对象字面量来创建一个对象
var obj={ };
console.log(typeof obj2);
代码示例:
<html>
<head>
<meta charset="utf-8">
<script>
var obj2={
name:"Xiao",
"Age":13,
gender:"man",
test:{
name:"big"
}
};
console.log(obj2.test);
</script>
</head>
<body>
</body>
</html>
p54 实参可以是任何值
函数返回值练习1
定义一个函数,判断一个数字是否为偶数,如果是返回true,否则返回false
<script>
//定义一个函数看是否为偶数
function isOu(num){
//看一个数与2相除是否
return num % 2 == 0;
}
var result=isOu(15);
console.log("result="+result);
</script>
函数返回值练习2
定义一个函数,可以根据半径计算一个圆的面积,并返回计算结果
<script>
function mianji(r){
var jisuan=3.14*r*r
return jisuan;
}
var result=mianji(4);
console.log("result="+result);
</script>
函数返回值练习3
创建一个函数,可以在控制台中输出一个人的信息
但是如果一个一个去写一个人的属性,那变量太多。容易出错
此时,我们可以用实参,实参可以是任意的数据类型,也可以是一个对象object,当我们的参数过多时,可以将参数封装到一个对象。然后通过对象传递
<html>
<head>
<meta charset="utf-8">
<script>
//o值object
function sayHello(o){
console.log("我的名字是"+o.name+",我今年"+o.age+"岁了,"+"我是一个"+o.gender+"人"+",我住在"+o.address);
}
//创建一个对象
var obj={
name:"sun",
age:19,
gender:"man",
address:"花果山"
};
sayHello(obj);
</script>
</head>
<body>
</body>
</html>
您甚至可以往里面传一个函数
function fun(a){
console.log("a"="+a);
a(obj);
}
fun(sayHello);
然后打印台会输出sayHello里的东西
把这个放到求面积那个函数里
fun(mianji(10));
打印台会输出面积
您还可以在函数里一层一层去套娃
function fun3(){
//在函数内部再声明一个函数
function fun4( ){
alert("我是fun4);
fun4();
}
//调用fun3
fun3()
控制台会输出警示框 “我是fun4”
p56立即执行函数
立即执行函数:函数定义完,立即被调用,这种函数叫做立即执行函数,立即执行函数往往只会执行一次。
p57 方法
//首先您先创建一个对象
//向对象中添加属性
obj.name="孙悟空";
obj.age=18;
//对象的属性值可以是任何的数据类型,也可以是个函数
obj.sayName = function( ){
console.log(obj.name);
};
//调用方法
obj.sayName( );
//调用函数
fun( );
枚举对象中的属性【使用for ... in 语句】
语法是
for(var 变量 in 对象){
语句...
}
官方解释
for...in语句:对象中有几个属性,循环体就会执行几次,每次执行时,会将对象中的一个属性的名字赋值给变量。
<script>
var obj={
name:"孙悟空",
age:18,
gender:"男",
address:"花果山"
};
for(var n in obj){
console.log("属性名:"+n);
console.log("属性值:"+obj[n]);
}
</script>
p57 函数的简介
函数function:
函数也是一个对象
创建函数方式1:
<html>
<head>
<meta charset="utf-8">
<script>
var fun = new Function()
//给函数添加属性
fun.hello="你好啊";
alert(fun.hello);
fun();
</script>
</head>
<body>
</body>
</html>
方式二:
<html>
<head>
<meta charset="utf-8">
<script>
function fun2(){
alert("haha");
document.write("sssssss");
}
fun2();
</script>
</head>
<body>
</body>
</html>
方式三:
<script>
var fun =function(){
document.write("nishigedashabi");
}
fun();
</script>
p58 全局作用域
1、作用域:
作用域是指一个变量的作用的番位
在js中一共有两种作用域
1、全局作用域 2、函数作用域
1、全局
直接写在script标签中的js代码,都在全局作用域
全局作用域在页面打开时创建,在页面关闭时销毁
在全局作用域中有个全局对象window,它代表的是一个浏览器的窗口,它由浏览器创建
我们可以直接使用
在全局作用域中,创建的变量都会作为window对象的属性保存,创建的函数都会作为window对象的方法保存。
全局作用域中的变量都是全局变量,在页面的任意的部分都可以访问的到。
<script>
var obj={
name:"孙悟空",
age:18,
gender:"男",
address:"花果山"
};
console.log(window.obj);
for(var n in obj){
console.log("属性名:"+n);
console.log("属性值:"+obj[n]);
}
</script>
//您也可以直接从window对象中直接输出值
window.alert("花果山");
会有一个警示框弹窗
变量的声明提前
变量的声明提前:
使用var关键字声明的变量,会在所有的代码执行之前被声明。(但是不会赋值)
但如果声明变量时不使用var关键字,则变量不会被提前声明
就比如说
var a;
console.log("a="+a);
a=123;
//因为一开始没有赋值,所以此时此刻输出等就是a=undefined
这个也是
console.log("a="+a);
var a=123;
//因为var声明在console后面,所以这里输出也是a=undefined
如果您先出入值在console语句之前但是您没有使用var
示例代码
a=123; //相当于window.a=123;
console.log("a="+a);
控制台输出a=123
但是如果你这样写
console.log("a="+a);
a=123;
这样就是报错,因为你没有使用var关键字,声明根本没提前。
函数的声明提前
使用函数声明形式创建的函数function函数( ){},它会在所有的代码被执行之前就被创建,所以我们可以在函数声明前来调用函数
就是您不能在创建这个函数之前就调用这个函数
p59 函数的作用域
函数作用域:
1、调用函数时创建函数作用域,函数执行完毕以后,函数作用域销毁。
2、每调用一次函数就会创建一个新的函数作用域,他们之间是互相独立的。
3、在函数作用域中可以访问到全局作用域的变量,在全局作用域中无法访问到函数作用域的变量。
4、当在函数作用域操作一个变量时,它会先在自身作用域中寻找,如果有就直接使用;如果没有则向上一级作用域中寻找,直到找到全局作用域;如果全局作用域中依然没有找到,则会报错ReferenceError。
5、在函数中要访问全局变量可以使用window对象。
//创建一个变量
var a=10;
function fun( ){
var="我是fun函数中的变量a";
var b=20;
console.log("a="+a);
function fun2( ){
console.log("a="+window.a);
}
fun2( );
}
fun( ); //调用fun函数时,首先会输出a=我时fun函数中的变量a
然后a=10,因为fun2中调用的window全局的值
console.log("b="+b);//这句话会报错因为全局作用域不能调用函数作用域中的值
函数作用域声明提前特性
使用var关键字声明的变量,会在函数中所有的代码执行之前被声明
函数声明也会在函数中所有的代码执行之前执行
如果您这样写
var e=23;
function fun5(e){
alert(4);
}
fun5();
这样返回值时undefined,因为fun5(e)是一个形参,然后您调用时fun5(); 括号里没有赋值,所以就变成undefined了
p60 debug
教你在各个浏览器里怎么查找报错用的
p61 this
解析器在调用函数每次都会向函数内部传递进一个隐含的参数,这个隐含的参数就是this,this指向的是一个对象,这个对象我们称为函数执行的上下文对象。
根据函数的调用方式的不同,this会指向不同的对象:
以函数的形式调用时,this永远都是window;
以方法的形式调用时,this就是调用方法的那个对象。
1、在函数的形式进行调用
<script>
function fun(a,b){
console.log("a="+a+",b="+b);
console.log(this);
}
fun(123,455);
</script>
<script>
function fun(){
console.log(this);
}
var obj={
name:"孙悟空",
sayName:fun
};
obj.sayName();//以方法形式调用,this是调用方法的对象
fun();//以函数形式调用,this是window
</script>
P63 63.尚硅谷_JS基础_使用工厂方法创建对象
p64构造函数
创建一个构造函数,专门用来创建Person对象的。
构造函数就是一个普通的函数,创建方式和普通函数没有区别,不同的是,构造函数习惯上首字母大写。
构造函数和普通函数的区别就是:调用方式的不同;
普通函数是直接调用,而构造函数需要使用new关键字来调用。
构造函数的执行流程:
- 立刻创建一个新的对象;
- 将新建的对象设置为函数中this,在构造函数中可以使用this来引用新建的对象;
- 逐行执行函数中的代码;
- 将新建的对象作为返回值返回。
<script>
function Person(){
alert("ssss");
}
var per = new Person();
</script>
instanceof:检查一个对象是否是一个类的实例
使用instanceof可以检查一个对象是否是一个类的实例。
语法:
对象 instanceof 构造函数
如果是,则返回true,否则返回false。
this使用情况的总结
this的使用情况:
- 当以函数的形式调用时,this是window;
- 当以方法的形式调用时,谁调用方法 this就是谁;
- 当以构造函数的形式调用时,this就是新创建的那个对象。
p66 原型对象
我们所创建的每一个函数(ps:函数也是对象),解析器都会向函数中添加一个属性prototype
<script>
function Person(){
}
console.log(typeof Person.prototype);
</script>
输出数据类型为object
每一个函数都有这个prototype属性
这个属性对应着一个对象,这个对象就是我们所谓的原型对象
如果函数作为普通函数调用prototype时没有任何作用
而当函数通过调用构造函数时,它所创建的对象中都会有一个隐含的属性,指向该构造函数的原型对象
我们可以通过( __proto__ )来访问该属性 tips:注意这里是两个下划线
function Person(){
}
var per=new Person();
console.log(per.__proto__ == Person.prototype);
//控制台会打印输出true
这个原型对象就相当于一个公共的区域,所有同一个类的实例都可以访问到这个原型对象
比如您这样写
var per1=new Person();
var per2=new Person();
console.log(per1.__proto__ == Person.prototype); //true
console.log(per2.__proto__ == Person.prototype); //true
于是我们可以将对象中共有的内容,统一设置到原型对象中
function Person(){
}
//向Persond的原型中添加属性a
Person.prototype.a=123;
var per=new Person();
var per1=new Person();
var per2=new Person();
console.log(per1.__proto__ == Person.prototype); //true
console.log(per2.__proto__ == Person.prototype); //true
console.log(per.a); // "123"
当我们访问对象的一个属性或方法时,先在自身对象属性就找,没有再去原型对象里去找。
所以此时您回到构造函数的那个例子里去
改成
<script>
<script>
function Person(name, age,gender){
this.name=name;
this.age=age;
this.gender=gender;
}
//向原型添加sayName方法
Person.prototype.sayName=function(){
alert("嗨,大家好,我是:"+this.name+
",我的年纪是:"+this.age)
};
var per=new Person("孙悟空",18,"男");
var per2=new Person("沙和尚",12,"男");
per.sayName();
per2.sayName();
</script>
//最后结果会输出
嗨,大家好,我是:孙悟空,我的年纪是:18
嗨,大家好,我是:沙和尚,我的年纪是:12
以后我们构建函数时,我们可以将这些对象共有的属性和方法,统一添加到构造函数的原型对象中
这样不用分别为每一对象添加,也不会影响到全局作用域,就可以使每个对象都具有这些属性和方法了。
function MyClass(){
}
//向MyClass的原型中添加一个name属性
MyClass.prototype.name="我就是原型的名字";
var mc= new MyClass( );
//检查一个函数中是否有某个属性
console.log("name" in mc); //true
使用in检查对象中是否含有某个属性时,如果对象中没有但是原型中有,也会返回true
如果您需要检查自身是否含有某个属性,这时就不能用in了
每个对象都有一个方法hasOwnProperty( ),可以使用该方法来检查对象自身是否含有某个属性
console.log(mc.hasOwnProperty("name")); //false
可是这个方法从哪儿来的呢
自身没有这个方法👇
console.log(mc.hasOwnProperty("hasOwnProperty")); //false
然后您去原型里去找
console.log(mc.__proto__.hasOwnProperty("hasOwnProperty")); //false
原型也是一个对象,所以它里面还有原型,所以您得去原型的原型里再去找找
console.log(mc.__proto__.__proto__.hasOwnProperty("hasOwnProperty"));
//此时返回true
console.log(mc.__proto__.__proto__.__proto__); //null
也就是说到第二个原型就到头了
p68 toString( )
function Person(){
}
var per=new Person();
console.log(per);
为什么控制台会输出object
当我们在页面上打印一个对象时,事件上输出的对象toString( )方法的返回值
这个toString( )方法在原型的原型里面
console.log(per.__proto__.__proto__.hasOwnProperty("toString"));//true
这个原型的原型的里toString方法里放的值就是[Object Object]
您现在不想要这个值,那您可以添加toString( )方法
per.toString =function( ){
return "我是一只快乐的小猪";
};
代码如下:
<script>
function Person(){
}
var per=new Person();
//如果希望在console输出对象per时不输出object
//可以为对象添加一个toString方法
per.toString=function(){
return "我是一只快乐的小猪";
}
var result=per.toString();
console.log("result"+result);
</script>
这样就会输出
result我是一只快乐的小猪
您再console.log(per);
也会输出:result我是一只快乐的小猪
因为您本身函数里就有这个方法
所以就不会再去外面找了
您发现这种方式只能修改一个值
您得修改Person原型的toString的值
Person.prototype.toString = function( ){
return "Person["name="+this.name+",age="+this.age+",gender="+this.gender]";
};
代码如下:
<script>
function Person(name, age,gender){
this.name=name;
this.age=age;
this.gender=gender;
}
//创建一个Person实例
var per=new Person("小明",14,"男");
var per2=new Person("八届",14,"美女");
//如果希望在console输出对象per时不输出object
//可以为对象添加一个toString方法
Person.prototype.toString = function( ){
return "Person[name="+this.name+",age="+this.age+",gender="+this.gender+"]";
};
console.log(per);
console.log(per2);
</script>
p69垃圾回收
一个程序运行过程中也会产生垃圾,这些垃圾积攒过多以后,会导致程序运行的速度过慢,所以我们需要一个垃圾回收的机制,来处理程序运行过程中产生的垃圾
所以我们必须进行清理
在js中拥有自动的垃圾回收机制,会自动地将这些垃圾对象聪内存中销毁,我们不需要也不能进行垃圾回收的操作
我们需要做的就是将不再使用的对象设置为null即可
var obj=new Object();
obj=null;
p70 数组简介
对象分为三种
1、内建对象(String Number Boolean Object Function)
2、宿主对象(BOM DOM等浏览器提供的对象)
3、自定义对象自己(var obj new Object)
数组(Array)
1、数组也是一个对象
2、它与我们普通对象功能类似,也是用来存储一些值
3、不同的是普通对象是使用字符串作为属性名的,而数组是使用数字来作为索引操作元素
4、索引:从0开始的证书就是索引
5、数组的存储性能比普通对象要好,在开发中我们经常使用数组来存储一些数据
//创建数组对象
var arr = new Array( );
console.log(arr);
//使用typeof检查一个数组时,会返回object
向数组中添加元素
<script>
//新建一个数组对象
var arr=new Array();
//向数组中添加元素
arr[0]=0;
arr[1]=22;
arr[2]=33
arr[3]=0;
arr[4]=234;
arr[5]=11;
//检测数组长度
console.log(arr.length);
//打印数组里的值
console.log(arr);
</script>
如果您漏掉一个元素
例如arr[3]的值您没写
<script>
//新建一个数组对象
var arr=new Array();
//向数组中添加元素
arr[0]=0;
arr[1]=22;
arr[2]=33
arr[4]=234;
arr[5]=11;
//检测数组长度
console.log(arr.length);
//打印数组里的值
console.log(arr);
</script>
数组长度不变,但是缺失值后都会标注索引:值;
查找数组中的元素,代码如下:
console.log(arr[0]); //0
console.log(arr[10]); //undefined
获取数组长度
console.log(arr.length); //6
修改数组长度
修改length:如果修改的length大于原长度,则多出部分会空出来。
如果修改的length小于原长度,则多出的元素会被删除。
数组字面量
使用“字面量”创建数组
与var arr =new Array( );创建数组的方式一样,但是[]更加简单、方便
代码示例:
var arr=[ ];
//使用字面量创建数组时候,可以在创建时就制定数组中的元素
var arr=[1,2,3,4,5,10]
console.log(arr.length); //6
console.log(arr[3]); //4
//使用构造函数创建数组,也可以同时添加元素
var arr2 =new Array(10,20,30);
console.log(arr2);
//创建一个长度为10的数组
arr2 =new Array(10);
console.log(arr2); //(10)[empty x 10]
数组中的元素可以是任意的数据类型
var arr=["hello",1,true,null,undefined];
对象数组
var obj={
name:"sunwukong"
};
console.log(arr[5]); //{name:"sunwukong"
console.log(arr[5].name); //sunwukong
函数数组
<script>
var arr=[function(){alert(1);},function(){alert(1);}];
arr[0]();
</script>
//输出后会弹出1
二维数组
p72
Array 对象属性
Array 对象方法
数组的遍历
所谓的的遍历数组,就是把数组中的所有元素都取出来
<script>
//创建一个数组
var arr=["s","z","s","t"];
//所谓的遍历数组,就是将数组中所有的元素都取出来
for (var i = 0;i<arr.length;i++){
console.log(arr[i]);
}
</script>
小练习
<script>
function Person(name, age,gender){
this.name = name;
this.age=age;
}
Person.prototype.toString=function(){
return "Person[name="+this.name+",age="+this.age+"]";
};
var per=new Person("孙悟空",18);
var per2 = new Person("猪八戒",13);
var per3= new Person("红孩儿",18);
var per4 = new Person("唐僧",10);
var per5 = new Person("二郎神",28);
//将这些person对象放入到一个数组中
var perArr=[per,per2,per3,per4,per5];
//创建一个函数,可以将perArr中满18岁的Person提取出来
//然后封装到一个新的数组中返回
function getAdult(arr){
//创建一个新的数组
var newArr=[];
//然后您需要遍历整个数组先
for(var i =0;i<arr.length;i++){
console.log(arr[i]);
var p=arr[i];
if(p.age>=18){
newArr.push(p);
}
}
//将新的数组返回
return newArr;
}
var result=getAdult(perArr);
console.log(result);
</script>
一般我们使用for循环去遍历数组,在js中还有一个方法遍历数组
forEach( ),但是这个方法只支持IE8以上的浏览器
forEach( )方法需要一个函数作为参数
像这种函数,由我们创建但是不由我们调用的,我们称为回调函数。
数组中有几个元素,函数就会执行几次,每次我执行时,浏览器会将遍历到元素,以实参的形式传递进来,我们可以定义形参。
浏览器会在回调函数中传递三个参数,第1个参数,就是当前正在遍历的元素,第2个参数,就是当前正在遍历元素的索引。第3个参数,就是正在遍历的数组
p79 call( )和apply( )
这两个方法都是函数对象的方法,需要通过函数对象来调用。
在调用call()和apply()可以将一个对象指定为第一个参数,此时这个对象将会成为函数执行时对this
call()方法可以将实参在对象之后依次传递
apply()方法需要将实参封装到一个数组中统一传递
代码示例:
var obj1={
name:"obj1",
sayNameLfunction( ){
alert(this.name);
};
obj1.sayName( ); //obj1
obj1.sayName.ao=apply( ); //
obj1.sayName.ao=apply( obj1); //obj1
例2
<script>
function fun(a,b){
console.log("a="+a);
console.log("b="+b);
}
var obj={
name:"obj",
sayName:function(){
alert(this.name);
}
};
fun.call(obj,4,5);
//apply()方法需要将实参封装到一个数组中统一传递
fun.apply(obj,[7,9]);
fun(2,3);
</script>
this使用情况总结
this的情况:
- 以函数形式调用时,this永远都是window;
- 以方法的形式调用时,this是调用方法的对象;
- 以构造函数的形式调用时,this是新创建的那个对象;
- 使用call和apply调用时,this是指定的那个对象。
js基础 arguments
在调用函数时,浏览器每次都会传递两个隐含的参数this、arguments
1、函数的上文对象this
2、封装实参的对象arguments
arguments是类数组对象,它也可以通过索引来操作数据,也可以获取长度
在调用函数时,我们所传递的实参都会在argument中保存
argument.length可以获取实参的长度。
我们即使不定义形参,也可以通过argument来使用实参。
只不过比较麻烦
argument[0]表示第一个实参
argument[1]表示第二个实参
代码示例:
function fun(a,b){
console.log(arguments[0]); //hello
console.log(arguments[1]); //true
}
fun("hello",true);
p81 Date( )对象
在JS中使用Date( )对象来表示一个时间
//创建一个Date对象
//如果直接使用构造函数创建一个Date对象,则会封装为当前代码执行的时间
var d =new Date( );
console.log(d);
Sat May 29 2021 14:18:06 GMT+0800 (CST)b
//创建一个指定的时间对象
<script>
var d2 =new Date("2/18/11");
console.log(d2);
</script>
Fri Feb 18 2011 00:00:00 GMT+0800 (CST)
//需要在构造函数中传递一个表示时间的字符串作为参数
<script>
var d2 =new Date("2/18/2011");
console.log(d2);
</script>
Fri Feb 18 2011 00:00:00 GMT+0800 (CST)
//日期的格式 月份/日/年 时:分:秒
<script>
var d2 =new Date("2/18/2011 10:11:30");
console.log(d2);
</script>
Fri Feb 18 2011 10:11:30 GMT+0800 (CST)
1、getDate():获取当前日期对象是几日
<script>
var d2 =new Date("2/18/2011 10:11:30");
var data =d2.getDate();
console.log(data);
</script>
//18
2、getDay( ):获取当前日期对象对应周几
<script>
var d2 =new Date("2/18/2011 10:11:30");
var day =d2.getDay();
console.log(day);
</script>
//6
获取当前日期对象周几时,会返回0~6的值,0表示周日,1表示周一
3、getMonth( ):获取当前时间对象的月份
<script>
var d2 =new Date("2/18/2011 10:11:30");
var month =d2.getMonth();
console.log(month);
</script>
//4
//0~11 o表示一月 1表示2月
4、getFullYear( ):获取当前日期对象的年份
<script>
var d2 =new Date("2/18/2011 10:11:30");
var year =d2.getFullYear();
console.log(year);
</script>
p82 Math对象
Math和其他的对象不同,它不是一个构造函数,它属于一个工具类,不用创建对象,里面封装了数学运算相关的属性和方法
比如 Math.PI表示圆周率
console.log(Math); // [object Math]
console.log(Math.PI);
Math对象用于执行数学任务。
Math对象并不像Date和String那样事对象的类,因此没有构造函数Math(),像Math.sin( )这样的函数只是函数,不是某个对象的方法,您无需创建它。通过Math作为对象使用就可以调用其所有属性和方法
1、Math.abs():计算一个数的绝对值
console.log(Math.abs(-1)); // 1
2、Math.ceil():可以对一个数进行向上取整,小数位只要有值就自动进1
3、Math.floor():可以对一个数进行向下取整,小数部分会被舍掉
4、Math.round():可以对一个数进行四舍五入取整
console.log(Math.ceil(1.1)); // 2
console.log(Math.floor(1.99)); // 1
console.log(Math.round(1.4)); // 1
5、Math.random():可以用来生成一个0-1之间的随机数
Math.random():可以用来生成一个0-1之间的随机数。 开区间(0,1)
生成一个0-10的随机数:Math.round(Math.random() * 10) // Math.round():四舍五入取整
生成一个0-x之间的随机数:Math.round(Math.random() * x)
生成一个1-10:Math.round(Math.random() * ( 10 - 1 ) + 1)
生成一个x-y之间的随机数:Math.round(Math.random() * ( y - x ) + x)
6、max():可以获取多个数中的最大值
7、min():可以获取多个数中的最小值
8、Math.pow(x,y):返回x的y次幂
9、Math.sqrt():用于对一个数进行开方运算
p83 包装类
在js中为我们提供三个包装类,通过这三个包装类可以将基本数据类型的数据转换为对象
1、String( ):可以将基本的数据类型字符串转换为String对象
2、Number( ):可以将基本数据类型的数字转换为Number对象
3、Boolean( ):可以将基本数据类型的布尔值转换为Boolean对象
//创建一个Number类型的对象,num=3;
var num =new Number(3);
var str=new String("hello");
var bool=new Boolean(true);
//向num中添加一个属性
num.hello = "abcdefg";
console.log(num.hello)
打印台输出abcdefg
p84 字符串的方法
String对象有哪些方法
01、length属性:获取字符串的长度
在底层字符串是以字符数组的形式保存的。["H","e","l"]
02、charAt():返回字符串中指定位置的字符(根据索引获取指定的字符)
03、charCodeAt():获取指定位置字符的字符编码(Unicode编码)
04、String.formCharCode():根据字符编码去获取字符
05、concat():用来连接两个或多个字符串(作用和+一样)
06、indexOf() / lastIndexOf():检索一个字符串中是否含有指定内容
indexOf()
该方法可以检索一个字符串中是否含有指定内容。
如果字符串中含有该内容,则会返回其第一次出现的索引,如果没有找到指定的内容,则返回-1。
可以指定一个第二个参数,指定开始查找的位置。
lastIndexOf()
该方法的用法和indexOf()一样,不同的是indexOf是从前往后找,而lastIndexOf是从后往前找。
也可以指定开始查找的位置。
是从后面(从右往左)往前找,寻找到最后出现的字符,再返回寻找到的这个字符从左到右的位置。
07、slice():从字符串中截取指定的内容
* slice()
* - 可以从字符串中截取指定的内容。
* - 不会影响原字符串,而是将截取到内容返回。
* - 参数:
* 第一个,开始位置的索引(包括开始位置)
* 第二个,结束位置的索引(不包括结束位置)
* - 如果省略第二个参数,则会截取到后边所有的
* - 也可以传递一个负数作为参数,负数的话将会从后边计算
08、substring():截取一个字符串,可以slice()类似
substring():可以用来截取一个字符串,可以slice()类似。
参数:
第一个:开始截取位置的索引(包括开始位置)。
第二个:结束位置的索引(不包括结束位置)。
不同的是这个方法不能接受负值作为参数,如果传递了一个负值,则默认使用0。
而且他还自动调整参数的位置,如果第二个参数小于第一个,则自动交换。
09、substr():用来截取字符串
参数:
- 截取开始位置的索引
- 截取的长度
10、split():将一个字符串拆分为一个数组
参数:
需要一个字符串作为参数,将会根据该字符串去拆分数组。
如果传递一个空串作为参数,则会将每个字符都拆分为数组中的一个元素。
11、toUpperCase():将一个字符串转换为大写并返回
12、toLowerCase():将一个字符串转换为小写并返回
p85 正则表达式的简介
正则表达式是干嘛的:
例如您注册邮件,格式错误的话您不能成功注册
我需要去检查这个格式是否正确
正则表达式用于定义一些字符串的规则
计算机可以根据正则表达式,来检查一个字符串是否符合规则。
获取将字符串中符合规则的内容提取出来。
//创建正则表达式的对象
语法:
var 变量=new.RegExp("正则表达式","匹配模式");
var reg=new RegExp("a");
此时这个字符串里的a就是一个正则表达式
正则表达式的方法:
test( )
使用这个方法可以检查一个字符串是否符合是否符合正则表达式的规则
符合返回true,不符合返回false
//这个表达式可以检测这个函数中是否含有小a 严格区分大小写
ver reg=new RegExp("a");
var str="a"
var result=reg.test(str);
console.log("result); //true
console.log(reg.test("bbbsc")); //false
如果您想不那么区分大小写,在构造函数中可以传递一个匹配模式作为第二个参数
可以是
i:忽略大小写
g:全局匹配模式
<script>
var reg=new RegExp("a","i");
var str="a";
console.log(reg.test("Adfa"));
</script>
//控制台打印输出true
使用字面量来创建正则表达式
语法:
var 变量=/正则表达式/匹配模式
//正则表达式
var reg=new RegExp("a","i");
//使用字面量来创建
<script>
reg =/a/i ;
console.log(reg.test("aggrgrgr"));
</script>
控制台输出true
创建一个正则表达式,检查一个字符串中是否有a,b,而且a和b还得挨着,调换位置都不行
reg= /ab/;
console.log(reg.test("bcsd"); //false
<script>
//使用|表示或者的意思
reg =/a|b/;
console.log(reg.test("bcd33rafaf"));
</script>
//true
<script>
//使用|表示或者的意思
reg =/a|b|e/;
console.log(reg.test("bcd33rafaf"));
</script>
[]:表示“或者”的意思
[]里的内容也是或的关系,[ab] == a|b。
[a-z]:任意小写字母
[A-Z]:任意大写字母
[A-z]:任意字母 这会出问题,因为在Unicode编码中A-z中存在6个非字母的字符,比如说 ^ 这个字符就属于[A-z]。
[0-9]:任意数字
创建一个正则表达式检查一个字符串中是否有字母:
<script>
//使用|表示或者的意思
reg =/[A-Z|a-z]/;
console.log(reg.test("990"));
</script>
//检查字符串是否含有a或者b
<script>
//使用|表示或者的意思
reg =/[ab]/
console.log(reg.test("a222f"));
</script>
[^ ]:除了
p87 字符串和正则相关的方法
1、split():将一个字符串拆分为一个数组
split()
- 可以将一个字符串拆分为一个数组。
- 方法中可以传递一个正则表达式作为参数,这样方法将会根据正则表达式去拆分字符串。
- 这个方法即使不指定全局匹配,也会全都插分。
2、search():搜索字符串中是否含有指定内容
search()
可以搜索字符串中是否含有指定内容。
如果搜索到指定内容,则会返回第一次出现的索引,如果没有搜索到返回-1。
它可以接受一个正则表达式作为参数,然后会根据正则表达式去检索字符串。
serach()只会查找第一个,即使设置全局匹配也没用。
3、match():根据正则表达式,从一个字符串中将符合条件的内容提取出来
match()
可以根据正则表达式,从一个字符串中将符合条件的内容提取出来。
默认情况下我们的match只会找到第一个符合要求的内容,找到以后就停止检索。我们可以设置正则表达式为全局匹配模式,这样就会匹配到所有的内容。可以为一个正则表达式设置多个匹配模式,且顺序无所谓。
match()会将匹配到的内容封装到一个数组中返回,即使只查询到一个结果。
4、replace():将字符串中指定内容替换为新的内容
replace()
- 可以将字符串中指定内容替换为新的内容。
- 参数:1.被替换的内容,可以接受一个正则表达式作为参数;2.新的内容。
- 默认只会替换第一个。
看
了
看
看