JavaScript

JavaScript

一、JavaScript简介

什么是语言?
  • 计算机有人控制
  • 计算机的语言去控制计算机
  • 编程语言是人与计算机交流的工具,语法比较特殊。
  • 机器语言(十进制、二进制)、符号语言比较难 我们现在用现代语言:高级语言(说话语法类似)。
起源
  • JavaScript诞生于1995年,用于处理网页中的前端验证
  • 用于前端的验证,查看是否符号用户输入规定

用浏览器检查 网景公司(Netscape)livescript是JavaScript的前身,Sun公司 node(服务器)。JScript微软刚 Microsoft 探险家

实现
  • ECMAScript.是一个标准 (两个词为一个意思)
  • 不同浏览器对该标准有不同的实现

学习有三个部分

——ECMAScrpt

——DOM

——BOM

特点

js的特点

-解释性语言

-类似于C和Java的语法结构

-动态语言

-基于原型的面向对象

js代码需要script标签

document(文档).write(写)

<script type="text/javascript">/*控制浏览器弹出警告框*/alert("这是一个警告框"); /*计算机在页面中输出内容*/document.write("会不会出来")【就是向body中写一个内容】; /*向控制台输入一个内容*/ console.log("你猜我在呢?") </script> 这三个为输出语句

按照从上到下逐行执行。

控制台只有开发人员去查看

<!--可以将js代码编写到标签的onclick(点击的意思)属性中

当我们点击代码是才能执行--> <button onclick="alert('你点我干嘛?');">点我一下</button> <!--可以将js代码写在超链接的href属性中,这样当点击超链接时,会执行js代码--><a href="javascript:alert('让你点就点');">你也点我一下</a>href="javascript:;">你也点我一下</a>

虽然可以写在标签的属性中,但是他们属于结构与行为耦合,不方便维护,不推荐使用。

  1. 可以将js标签写到script标签中

  2. 可以写在外部(–.js)通过script标签引入 ,写到外部文件中可以在不同的页面中同时引用,也可以利用浏览器的缓存机制。(推荐使用)

    一旦用于引入外部文件了,就不能在编写代码了,即使编写了浏览器也不显示

    如果想写 可以创建一个新的script标签用于编写

    <script type="text/javascript" src="js/··.js"></script>

  3. 可以编写在标签的内部(不推荐)

js的基本语法

js的注释

多行注释:/* */

多行注释,注释中的内容不过不会被执行,但是可以在源代码中查看

单行注释//

要养成良好写注释的习惯,也可以通过注释来对代码进行一些简单的调试。

注意
  1. js中严格区分大小

  2. js每一条语句以分号(;)结尾

    -如果不写分号,浏览器会自动添加,但是会消耗写系统资源,

    ​ 而且有些时候,浏览器会加错分号,所以在开发中分号必须写

  3. js中会忽略多个空格和换行,所以我们可以利用空格和换行对代码进行格式

字面量和变量

字面量,都是一些不可改变的值。 比如:1 2 3 4 5 |

字面量都是可以直接使用的,但是我们一般都不会使用字面量

变量 变量可以用来保存字面量 ,而且变量 的值可以任意改变的

​ 变量更加方便我们使用,所以在开发中都是通过变量去保存一个字 面量,而很少直接使用字面量

​ 通过变量对于字面量进行描述

声明变量

在js中使用var关键字来声明一个变量

var a; /*变量赋值*/a=123; console.log(a);

/*声明赋值同时进行*/ var b=0;

标识符

标识符:在js中所有的可以由我们自主命名的都可以成为是标识符

例如:变量名、属性名、函数名都属于标识符。

命名一个标识符需要遵守如下规则:
  1. 标识符中可以含有字母、数字。_、$。

  2. 标识符不能以数字开头。

  3. 标识符不能使用ES中的关键字或保留字。

  4. 标识符一般都采用驼峰命名法。

    首字母小写每个开头字母大写其余字母小写。(helloWorld)

var a_1_$=123; console.log(a_1_$);

JS底层保存标识符时实际上是采用的Unicode编码。 所有理论上讲,所有的utf-8中含有的内容都可以作为标识符。

(千万不要用中文命名)

数据类型

数据类型指的是字面量的类型。

在JS中一共有六种数据类型

  1. String 字符串
  2. Number 数值
  3. Boolean 布尔值
  4. Null 空值
  5. Undefined 未定义
  6. Object 对象

其中String、Number、Boolean、Null、Undefined 属于基本数据类型,object属于引用数据类型。

String 字符串 在JS 中字符串需要引号引起来(" ")。

使用双引号或单引号都可以,但是不要混使用

引号不能嵌套,双引号不能嵌套双引号,单引号不能嵌套单引号,单引号能嵌套双引号

在字符串中我们可以使用\作为转义符,党表示一些特殊符号时可以使用\进行转义

\'表示' \"表示" \n表示换行 \t表示制表符 \\表示\

注意:一个变量只能声明一次

Number 数值

在JS中所有的数值都是Number类型,包括整数和浮点数(小数)

通过使用运算符typeof来检查一个变量的类型

语法:typeof 变量 检查字符串时,会返回string;检查数值时,会返回number。

console.log(typeof a);

JS中可以表示的数字的最大值:Number.MAX_VALUE

如果使用number表示的数字超过了最大值,则会返回一个Infinity(正无穷)-infinity(负无穷) ,表示无穷大∞。 使用typeof检查infinity也表示是number

NaN 是一个特殊的数字 表示not A number。 使用typeof检查也会返回number。

JS中0以上的最小值:Number.MIN_VALUE

在JS中整数的计算基本上可以保证精确

如果使用JS进行浮点运算,可能得到一个不精确的结果。所有千万不要使用js进行对于精确度比较高要求的运算。

Boolean 布尔值

布尔值只有两个 ,主要用于逻辑运算。

true- 真

false-假

Null 空值

Null类型的值只有一个,就是null

null这个值专门用来表示空的对象 使用typeof检查null值时,会返回object

Undefined 未定义

Undefined 类型的值只有一个,就是Undefined

当声明一个变量,但是并不给变量赋值时,它的值就是undefined

使用typeof检查undefined值时,会返回undefined

强制类型转换

指将一个数据类型强制转换回其她的数值类型

类型转换主要指,将其他数据类型,转换为String、Number、Boolean

将其他的数据类型转换为String

方式一:

​ -调用被转换数据类型的toString()方法。

​ —该方法不会影响到原变量,它会将转换的结果返回

​ -但是注意,null和undefined这两个值没有toString()方法。

​ 如果调用他们的方法会报错。

方式二:

​ -调用String()函数,并将被转换的数据作为参数 a=String(a);

​ 使用String( )函数做强制类型转换时,

​ 对于Number和Boolean实际上就是调用toString()方法

​ 但是对于null和undefined,就不会调用toString()方法

var a=123;

//调用a的toString()方法``调用xxx的yyy()方法,就是xxx.yyy()

a.toString();

转换为Number
转换方式一:

使用Number( )函数

​ -字符串----> 数字

​ 1.如果字符串中有纯数字类型,则直接转换为数值

​ 2.如果有非数字类型,则直接转换为NaN

​ 3.如果字符串中是空串 ,或全部是空格则转换为0.

-布尔–>数字

​ true 转为1 false转为0

​ -Null–>数字 0

​ -Undefined -->数字 NaN

转换方式二:

​ -专门针对字符串的

​ -parseInt()把一个字符串转换为一个整数

​ -parseFloat()把一个字符串转换为一个浮点数

parseInt()可以将一个字符串中的有效的整数内容取出来 然后转换为Number

parseFloat()作用和parseint类似,不同的是这个可以取出有效的小数

如果对非string使用parseInt()parseFloat() 他回西安转换为string再进行操作。

其他的进制的数字

在js中,如果需要表示16进制的数字,需要以0x开头;如果需要8进制的数字,则需要以0开头;如果需要表示2进制的数字,则需要以0b开头。但不是所有浏览器都支持。

a = 0x10; console.log(a);

a=070;

a=0b10;

//向“070”这种字符串,有些浏览器当成八进制进行解析,有些当成10进制解析

a=parseInt(a,10); 可以在parseInt()中传递一个第二个参数,来制定数字的进制。

转换为布尔值

使用Boolean()函数

​ -数字----->布尔

​ -除了0和NaN, 其余的都是true

-字符串—>布尔

​ -除了空串,其余的都是true

–null和undefined都会转换为false

-对象也会转换为true

调用Boolean()函数转换为布尔值

运算符

运算符也叫操作符

通过运算符可以对一个或多个值进行运算,并获取运算结果

比如:typeof就是运算符,可以来获得一个值的类型

var result = typeof a;

它会将该值的类型以字符串的形式返回

number string Boolean undefined object

算数运算符

当非Number的值进行运算时,会将这些值转换为Number然后进行运算

任何值与NaN进行运算都是NaN

+可以对两个值进行加法运算,并将结果返回

*(只有+法)如果对两个字符串进行加法运算 将两个字符串拼接为一个字符串,并返回

任何的值与字符串进行加法运算,都会先转化为字符串,之后进行拼串。

result = a+1;

将数值转换为字符串

c=c+'';(隐式类型)

console.log("c="+c);

-会对两个值进行减法运算并对结果返回

*可以对两个值进行乘法运算

/可以对两个值进行除法运算

任何值进行-*/都会自动转换为number 我们可以利用这一特点做隐式的类型转换可以通过 — */ 0.

%取余数运算

一元运算符

只需要一个操作数

+正号 正号不会对数字产生影响

var a=123; a=+a console.log(a)

-负号 对数字进行负号的取反

-对于非Number类型的值,

它会将先转换为Number,然后再运算

可以对其他的数据使用正号将其他类型转换为number。它的原理和number()函数一样。

varresult=1+"2"+3;console.log("result="+result)

自增和自减

自增(++):通过自增可以使变量在自身的基础上增加1

var a=1;a=a+1;console.log("a="+a);

a++; 使a增加1 ++a;

对于一个变量自增以后,原变量的值会立刻增加1

自增分为两种:后++(a++)和前++(++a)

无论是a++还是++a,都会使原变量的值自增1

不同的是a++和++a的值不同

a++的值等于原变量的值(自增前的值)

++a的值等于原变量新值(自增后的值)

var c=10;
//第一次c++,是在10的基础上自增
c++;
//第二次c++,是在11的基础上自增
console.log(c++);
var d = 20;
//20 +22 +22
var result=d++ + ++d + d;
console log("result="+result);
d = d++;
//var e =d++;
//d=e;
console.log("d="+d);

自减:通过自身的基础上减1

var num = 10;
num--;
console.log("num="+num);

自减也分为两种,后–(a–)和前–(--a)

无论是a–还是–a都会使原变量的值自减1

不同的是a–和--a的值不同 a–是变量的原值(自减前的值) --a是变量的新值(自减后的值)

练习

var n1=10,n2=20; //逗号表示同时声明两个变量
var n = n1++;  //n1=11, n1++=10
console.log("n="+n); //n=10
console.log("n1="+n1);//n1=11
n=++n1; //n1=12  ++n1=12
console.log("n="+n);//12
console.log("n1="+n1);//12
n=n2--;//n2=19  n2--=20
console.log("n="+n); //20
console.log("n2="+n2);//19
n=--n2;//n2=18  --n2=18
console.log("n="+n);//18
console.log("n2="+n2);//18
逻辑运算符

js中为我们提供了三种逻辑运算符

**! 非 ** !可以用来对一个值进行非运算

所谓非运算就是对一个值取反 。true变false

如果对一个值进行两次取反 ,它不会变

如果对非布尔值进行元素,则会将其转换为布尔值,然后再取反。 所以我们可以利用该特点将其他类型换换成布尔值。可以为任意数据类型去两次反,将其转换为布尔值。

&& 与 &&可以对符号两侧的值进行与运算并返回结果。

两个值中,只要有一个值为false都返回false

只有都为true时才会返回true.

JS中的“与”属于短路与,如果第一个值为false,则不会看第二个。

|| 或 ||可以对符号两侧的值进行或运算并返回结果

运算规则:

两个值中都是false才会返回false,

两个值中只有一个true都会返回true.

JS中的“或”属于短路或,如果第一个值为true则不会检查第二个。 第一个值为false则会检查第二个。

var a = true;
a = !a;
console.log("a="+a);//false
//如果两端都是true则返回true。
var result=true&&true;
//只要有一个false就返回false
result=true&&false;
result=false&&false;
console.log("result="+result);
//第一个值为true,会检查第二个值
true&&alert("出来");
//第一个值为false,不会检查第二个值
false&&alert("出来");
//两个都是false则返回false
result = false || false;
//只有有一个true就返回true
result = true || false;
result = true || true;
console.log("result="+result);
逻辑运算

&& || 非布尔值的情况

对于非布尔值进行与或运算时,

回向将其转换为布尔值,然后在运算,并且返回原值

与运算:

如果第一个是true,则必返回第二个值

如果第一个值是false,则必返回第一个值

或运算:

如果第一个值为true,则直接返回第一个值

如果第一个值为false,则直接返回第二个值

//与运算:如果两个值都为true,则返回靠后的
var result 1&&2;
//false&&true  如果false则返回靠前的false
result=0&&2;
result=NaN&&0;
console.log("result="+result)

//如果第一个值为true,则直接返回第一个值。
result = 2||1;
//如果第一个值是false,则直接返回第二个值
result = 2||NaN;
result = 2||0;
result=NaN||1;
result=""||"hello";//返回hello
console.log("result="+result);
赋值运算符

= :可以将符号右侧的值赋值给符号左侧的变量

+=:a +=5等于a=a+5;

-=:a -=5等于a=a-5;

*=:a *=5等于a=a *5;

/=:a /=5等于a=a/5;

%=:a %=5等于a=a%5;

var a-123;
//a=a+5;
a+=5;
console.log("a="+a);
关系运算符

通过关系运算符可以比较两个值之间的大小关系

如果关系成立它返回true,如果关系不成立则返回false

大于号

判断符号左侧的值是否大于右侧

如果关系成立则返回true,如果关系不成立则返回false.

大于等于>=

判断符号左侧的值是否大于或等于右侧值如果关系成立则返回true如果不成立则返回false.

<小于:如果关系成立则返回true,如果关系不成立则返回false.

<=:如果关系成立则返回true,如果关系不成立则返回false.

非数值的情况

对于非数值进行比较,会将其转换成数值进行比较。

如果符号的值两侧都是字符串,不会将其转换为数字比较,两侧会分别比较字符串的代码Unicode编码

var result = 5>10;//false
console.log("result="+result);
console.log(1>=true);//true
console.log(10<="hello");
//任何值跟NaN进行比较都是false.
console.log("a"<="b");//true
console.log("abc"<"b");//true
//比较字符串编码时一位一位的比较
//如果两位一样则比较下一位,借用它来对英文进行排序
//比较中文是没有意义的
//如果比较两个字符串行的数字,可能会得到不可能的结果
//注意:在比较两个字符串型的数字时,一定一定要进行转型
Unicode编码

在字符串中使用转义字输入Unicode编码

\u四位编码

console.log("\u0031");


<!--在网页中使用Unicode编码
&#编码;-->
<h1 style="fint-size:">&#2620;</h1>
相等运算符

用来比较两个运算符是否相等

如果相等则返回true,否则返回false

使用==来做相等运算

当使用==来比较类型转换,将其转换为相同的类型然后在比

var a=10;
console.log(a == 4);//false
console.log("1"==1);//true 类型转换、
console.log("1" == true);
console.log(null==0);//false

undefined 衍生自null

所以这两个值做相等判断时,会返回true.

NaN不和任何值相同,包括它本身

var b = NaN;
//判断b的值是否是NaN
//console.log(b == NaN);
/*
*可以通过isNaN()函数来判断一个值是否是NaN
如果该值是NaN则返回true,如果不是则返回false
*/
console.log(isNaN(b));

不相等

用来判断两个值是否不相等,如果不想等则返回时true,相等时返回false.不相等也会进行自动类型转换,如果转换后值相等也会返回false.

console.log(10!=5);//true
console.log(10!=10);//false
console.log(1="1");//false

===全等

用来判断两个值是否全等,它与相等类似,不同的是它是不会自动的类型转换。如果两个值的累性不同也会返回false.

console.log("123"===123);//false
console.log(null === undefined);//false

!==不全等

用来判断两个值是否不全等,和不等类似,不同的是它如果两个值返回true。

条件运算符

条件运算符又叫三元运算符

语法:

条件表达式?语句1:语句2;

执行的流程:

条件运算符在执行时,首先对条件表达式进行求值,如果值为true,则执行语句1,并返回执行结果;如果值为false,则执行语句2,并返回执行结果。

如果条件表达式的求值结果是一个非布尔值,将其转换成布尔值再运算。

true?alert("语句1"):alert("语句2");//语句1
false?alert("语句1"):alert("语句2");//语句2
// a>b?alert("a大"):alert("b大");
//获取a和b的最大值
var max = a>b? a:b;
//获取 a b c 中的大值
max = max >c ? max : c;
//这个写法不推荐使用,不方便运算
var max = a>b?(a>c?a:c) :(b>c?b:c);
console.log("max="+max);

运算符的优先级

(,)运算符 使用,运算符可以分割多个语句,一般可以在生命多个变量时使用,使用(,)运算符同时声明多个变量

//var a,b,c;
//可以同时声明多个变量并赋值
var a=1,b=2,c=3;
alert(b);

和数学中一样,在JS中也有优先级。比如先乘后减.

在JS中有一个运算符优先级的表,

在表中越靠上优先级越高,优先级越高越优先计算,

如果优先级一样则从左往右算。

//如果||的优先级高则返回3,如果与的优先级高则返回1
var result = 1 + 2*3;
var result = 1 || 2 && 3;
console.log("result="+result);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JyhiguG8-1634029094228)(D:\前端\练习\钛媒体\img\优先级.png)]

用()可以改变优先级

语句
代码块

我们的程序是由一条语句构成的。语句是按照自上往下的顺序一条一条执行的,在JS中可以使用{}来为语句进行分组。

在同一个{}中的语句我们称为是一组语句,它们要么都执行,要么都不执行。

一个{}中的语句我们也称为叫一个代码块

在我们代码快的后面就不用编写符号;了

JS中的代码块只具有分组的作用。没有其他的用途。

代码块内部的内容,在外部是完全可见的。

{
    alert('');
    console.log('');
    document.write('');
}

流程控制语句

JS中的程序是一行一行执行的

alert('hello');
console.log('你好');

相当于一个傻小子只会往前走不会拐弯。程序也是一样的只会向前直行。

条件分支(条件判断语句)使我们的程序更加智能。

通过流程控制语句可以控制程序执行流程,是程序可以根据一定的条件来选择执行。

语句的分类:

  1. 条件判断语句(如果条件成立就执行,如果不成立就不执行)
  2. 条件分支语句(如果满足分支中的一个就根据该分支继续执行)
  3. 循环语句(反复的执行该语句)
条件判断语句

使用条件判断语句可以在执行某个语句之前进行判断,如果条件成立则执行该语句,条件不成立则语句不执行。

if语句

语法一:

if(条件表达式)

语句

if语句在执行时,会先对条件表达式进行求值判断,如果条件表达式的值为true,则执行if语句;如果条件表达式是false,则不会执行if语句。

if语句只能控制紧随其后的那个语句;如果希望if语句可以控制多条语句,可以将这些语句统一放到代码块中

if语句后的代

码块不是必须的,但是在开发中尽量写上代码块,即使if后只有一条语句

if(true)
    alert("你猜我会出来吗?");//执行
if(false)
    alert("你猜我会出来吗?");//不执行
var a=10;
if(a>10)
{
    alert("a比10大~~~");//不执行
    alert('谁也管不了我~~~');
}
var a= 5;
if(a>10&&a<=20){
    alert("a大于10并且a小于等于20")
}

if语句

语法二:

if(条件表达式){

语句。。。}else{

语句。。。}

if…else…语句

当该语句执行时,会先对if后的条件表达式进行求值判断。。。

如果该值为true,则执行if后的语句

如果该值为false,则执行else后的语句

var age=60;
if(age>=60){
      alert("你已经退休了~~");
}else{
    alert('你还没退休~~~');
}

语法三:

if(条件表达式){

语句。。。}else if(条件表达式){

语句。。。}else{

语句。。。}

if…else if…else

当着语句执行时,从上到下依次执行对条件表达式进行求值判断

如果值为true,则执行当前语句,如果值为false,则继续向下判断。

如果所有的条件都不满足,则执行最后一个else语句。

该语句中,只有一个代码块的一句执行,直接结束。

var age=100;
if(age>100){
    alert('活着挺没有意思的~~~');
}else if(age>80){
    alert('你这也老大不小了~~~')
}else if(age>60){
    alert('你也退休了~~');
}else if(age>30){
    alert('你已经中年了~~');
}else if(age>17){
    alert('你已经成年了')}else{
    alert('你还是个小孩子~~');
}
var age=60;
if(age>17 && age<=30){
    alert("你已经成年了");
}else if(age>30&&age<=60){
    alert("你已经退休了");
}else if(age>60 && age<=80){
    alert("你已经退休了");
}else{
    alert("你岁数挺大的了~~");
}

练习:

从键盘输入小明的期末成绩:当成绩为100时,‘奖励以辆BMW’;当成绩为【80-99】时,‘奖励一本iphonel5s’;当成绩为【60-80】时,‘奖励一本参考书’;其他的,什么奖励都没有。

prompt()可以弹出一个提示框,该提示框中会带有一个文本框,用户可以在文本框中输入 一段内容,该函数需要一个字符串作为参数。

该字符串将会作为提示文字

用户输入的内容将会作为函数的返回值返回,可以定义一个变量来接收该内容

//score就是小明的期末成绩
var score=prompt('请输入小明的成绩(0-100):');
alert(score);
var score = 100;
//根据score的值来决定给小明什么奖励
if(score>=0 || score<=100 || isNaN(score) ){
   alert("请好好输出");
}else{
    if(score == 100){
    //奖励一台宝马
    alert("宝马,拿去~~~");
    }else if(score>=80){
    alert("奖励一台手机");
    }else if(score>=60){
    alert("奖励一个本参考书");
    }else{
    alert("努力学习");
    }
}

大家都知道,男大当婚,女大当嫁。那么女方家长要嫁女儿,当然要提出一定的条件:高:180cm以上;富:1000万以上;帅:500以上;
如果这三个条件同时满足,则:‘我一定要嫁给他’
如果三个条件有为真的情况,则:嫁吧,比上不足,比下有余。"如果三个条件都不满足,则:不嫁!‘

var height=prompt("请输入你的身高(CM)");
var money=prompt("请输入你的财富(万)");
var face=prompt("请输入你的颜值(PX)");
//alert(height+','+money+','+face);如果这三个条件同时满足,则:'我一定要嫁给他'
if(heigh>180 &&money>1000&& face>500){
    alert("我一定我要嫁给他");
}else if(heigh>180 || money>1000 || face>500){
    alert("嫁吧,比上不足,比下有余。");
}else{
    alert("不嫁!");
}

编写程序,由键盘输入三个整数分别存入变量mun1、num2、num3.

对他们进行排序,并且从小到大输出。

var num1=+prompt("请输入第一个数:");
var num2=+prompt("请输入第二个数:");
var num3=+prompt("请输入第三个数:");
//找到三个数中最小的数
if(num1 <num2 && num1<num3){
    //num1最小
    if(num2<num3){
        alert(num1+','+num2+','+num3);
    }else{
        alert(num1+','+num3+','+num2);
    }
}else if(num2<num1&&num2<num3){
    //num2最小
    if(num1<num3){
        alert(num2+','+num1+','+num3);
    }else{
         alert(num2+','+num3+','+num1);
    }
}else{
    //num3最小
    if(num1<num2){
        alert(num3+','+num1+','+num2);
    }else{
        alert(num3+','+num2+','+num1);
    }
}


num=10 是赋值
num==10 是等于
num===10 是绝对等于
条件分支

条件分支语句也叫(switch)语句

语法:

​ switch(条件表达式){

​ case 表达式:

​ 语句。。。

​ break;

case 表达式:

​ 语句。。。

​ break;

case 表达式:

​ 语句。。。

​ break;

case 表达式:

​ 语句。。。

​ break;

default:

​ 语句。。。

​ break;

}

执行流程:

switch…case…语句

​ 在执行时会依次将case后的表达式的值和switch后的条件表达式的值进行全等比较。

如果比较结构为true,则从当前case进行比较。当前case后的所有的代码都会执行,我们可以确保只会执行当前case后的语句,而不会执行其他的case

如果比较结构为false,则继续向下比较。

如果所有语句都为false,则执行default后的语句

switch语句和if语句的功能实际上有重复的,使用switch可以实现if的功能,同样使用if 可以实现switch的功能。所有我们使用时根据自己的习惯选择。

//根据num的值,输出对应的中文
var num=1;
if(num==1){
    console.log("壹");
}else if(num==2){
    console.log("贰");
}else if(num==3){
    console.log("叁");
}
switch(num){
    case 1:
        consle.log("壹");
        break;
    case 2:
        console.log("贰");
        break;
    default:
        console.log("非法数字~~");
        break;
}

对于成绩大于60的输出合格,否不合格

var score=60;
switch(parseInt(score/10)){
    case 10:
    case 9:
    case 8:
    case 7:
    case 6:
        consolelog("合格");
        break;
    default:
        console.log("不合格");
        break;
}
switch(true){
    case score>=60:
        console.log("合格");
        break;
    default:
        console.log("不合格");
        break;
}

循环语句

向页面中输出连续的数字

var n=1;
document.write(n++ +"<br / >");

document.write(2+"<br />");

通过循环语句可以返回的执行一段代码多次

while(条件表达式){
    语句。。。
} 
var n = 1;
//像这种讲条件语句写死为true的循环,叫做死循环
//这循环不会停止,除非浏览器关闭,死循环才结束,死循环在开发中慎用
//可以使用break退出循环
while(true){
    alert(n++);
    //判断m是否是10
    if(n==10){
           //退出循环
    break;
    }
}

while语句在执行时,先对条件表达式进行求值判断,如果值为true,则执行循环体,循环执行完毕以后,继续对表达式进行判断。如果为true,则继续执行循环体 ,依次类推;如果值为false,则终止循环。

创建一个循环,往往需要三个条件

1.创建初始化的一个变量

var i=0;

2.在循环中设置一个条件表达式

while(i<10){

alert(1);}

3.定义一个更新表达式,每次更新初始化变量

i++;

do…while循环

语法:

do{

语句。。

}while(条件表达式)

do{
    document.write(i++ +"<br />");
}while(i<=5000);

执行流程:

do…while语句在执行时,会先执行循环体,循环体执行完毕后,在对while后的条件表达式进行判断。如果为true,则继续执行循环体,然后判断。如果为false,则循环结束。

实际上这两条语句功能类似,不同的是while是先判断后执行。do…while实现执行后判断。

do…while可以保证循环体至少执行一次,而while不能。

例题:

假如投资的年利率为5%,试求从1000块增长到5000块,需要花费多少年?

//定义一个变量
var money=1000;
//money*=1.05;
//money*=1.05;
//money*=1.05;
//定义一个计数器
var count=0;
while(money<5000){
    money*=1.05;
    count++;
}
//console.log(maoney);
clonsole.log("一共需要"+count+"年");


for循环

for语句,也是一个循环语句,也称for循环

在for循环中,为我们提供了专门的三个表达式:

1.初始化表达式

2.条件表达式

3.更新表达式

for循环语法:

for(初始化表达式;条件表达式;更新表达式){

语句。。。

}

执行流程:

1.初始化表达式,初始化变量(初始化表达式只会执行一次)

2.条件表达式,判断是否执行循环;如果为true则执行循环,如果为false,终止循环。

3.执行更新表达式,更新表达式执行完毕,继续执行第二步

创建一个执行10次while循环

 //初始化表达式
var i=0;
//创建一个循环,定义条件表达式
while i<10{
    //设置更新表达式
    alert(i++);
}
for(var i=0;i<10;i++){
    alert(i);
}
var i=0;
for(;i<10){
    alert(i++);
}
for(;;){
    alert("");
}

for循环中的算个部分都可以省略,也可以写在外部

如果在for循环中不写任何表达式只写两个分号;此时循环是一个死循环,会有执行下去。

例题:

//打印1-100之间所有的奇数和
//创建一个变量,用来保存奇数之和
//var sum=0;
for(var i=1,sum=0;i<=100;i++){
    //只打印奇数
    //不能被2整除的就是奇数
    if(i%2!=0){
        sum+=i;(sum=sum+i)
        console.log(i);
    }
    //console.log(i);
}console.log(sum);
//打印1-100之间所有7的倍数的个数及总和
//计数器
var count=0;
for(var i=1,sum=0;i<=100;i++){
    if(i%7==0){
        sum+=i;
        coun++;
        console.log(i);
    }
}
console.log("七的倍数和为:"+sum);
//输出总数
console.log("总数是"+count);
//水仙花数   水仙花是指一个3位数,它的每个位上的数字是3次幂之和等于它本身,(例如1^3+5^3+3^3=153),请打印所有的水仙花数
//打印所有的三位数
for(var i=100;i<1000;i++){
    //获取i的百位 十位 个位的数字 
    //获取百位数字
    var bai=parseInt(i/100);
    //获取十位数字
    var shi=parseInt((i-bai*100)/10);
    //个位数字
    var ge=i%10;
    //console.log(bai);
//判断i是否是水仙花
    if(bai*bai*bai+shi*shi*shi+ge*ge*ge ==i){
        console.log(i);
    }
}
for练习
//测试如下程序的性能;在程序执行前,开启计时器;console.time("计时器的名字")可以用来开启一个计时器;他需要一个字符串作为参数,这个字符串将会作为计时器的标识。
console.time("test");


//在页面中接受一个用户输入的数字,并判断该数是否是质数。质数:只能被1和它自身整除的数,1不是质数也不是合数,质数必须是大于1的自然数。
var num=prompt("请输入一个大于1的数");
//判断值是否合法
if(num<=1){
    alert("该值不合法!");
}else{
    //创建一个变量来保存当前的数的状态
    //默认当前num是质数
    var flag=true;
    //判断num是否是质数
    //获取2~num之间的数
    for(var i=2;i<=Math.sqrt(num);i++){
        console.log(i);
        //判断num是否能被i整除
        if(num%i==0){
            //如果num能被i整除说明num一定不是质数
            //alert(num+"不是质数");
            //设置flag为false
            flag=false;
            //一旦进入判断,则证明num不可能是质数了,此时循环在执行已经没有任何意义了;使用break来结束循环。
            break;
        }
    }
    //如果num是质数则输出
    if(flag){
        alert(num+"是质数");
    }else{
        alert("这个不是质数");
    }
}
//终止计时器;console.timeEne()用来停止一个计时器,需要一个计时器的名字作为参数。
console.timeEnd("test");
//通过反方向推理来获得数据

//可以通过Math.sqrt()对一个数进行开方
//var result=Math.sqrt(4);
//console.log("result="+result);
嵌套的for循环

通过程序,在页面中输出如下的图标:

*
**
***
****
*****
 for (var i = 1; i <= 5; i++) {
            for (var j = 1; j <= i; j++) {
                document.write("*");
            }
            document.write("<br />");
        }
    
    
    
    
*****
*****
*****
*****
*****
//向body中输出一个内容
 document.write("******<br />");
 document.write("******<br />");
 document.write("******<br />");
 document.write("******<br />");
 document.write("******<br />");
for(i=1;i<=5;i++){
    //这个for循环几次,图形就增高多少  可以控制图的高度
    //document.write("******<br />");
   // document.write("*");
    //再循环中嵌套循环,控制宽度的;目前外不循环执行一次内部执行5次
    //内从循环可以绝对图形的宽度,执行几次宽度多少
    for(j=1;j<=5;5++){
        document.write("*");
    }
    //输出换行
}document.write("<br />");
//倒三角

        for (var i = 0; i < 5; i++) {
            for (var j = 0; j < 5 - i; j++) {
                document.write("*");
            }
            document.write("<br />");
        }

//打印九九乘法表
for(var i=1;i<=9;i++){
    for(var j=1;j<=i;j++){
     document.write(j+"*"+i);   
    }document.write("<br />");
}
//打印出1~100中所有的质数
var flag=true;
for(var i=2;i<=100;i++){
  //  console.log(i);
    for(var j=2;j<i;j++){
       // console.log("----->"+j);
        if(i%j==0){
            var flag=false;
               flag=false;
        }
    }
    //如果num是质数则输出
    if(flag){
        alert(num+"是质数");
    }else{
        alert("这个不是质数");
    }
}

break和countinue

break关键字可以用于退出switch或循环语句;不能在if语句中使用break和continue

break关键字,会终止离他最近的循环语句。

可以给循环创建一个label,来表示当前的循环

label:循环语句

使用break语句时,可以在break后跟一个label,这样break将会结束指定的循环,而不是最近的。

continue关键字可以跳出当前循环。同样continue也是默认离他最近的循环起作用。

hello:
for(var i=0;i<5;i++){
console.log("@外循环"+i);
    for(var j=0;j<5;j++){
        break hello;
        console.log("内循环:"+j);
    }
}
fot(var i=0;i<5;i++){
    if(i==2){
        continue;
    }console.log(i);
}
对象

JS数据类型:

简单型(基本数据类型):String 字符串 Number 数值 Boolean 布尔型 Null 空值 Undefined 未定义

以后我们看到的只要不是上面五种,都是对象。

复杂型(引用数据类型): Object 对象

基本数据类型都是单一的,他们之间是没有联系的。

在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关键字调用的函数,是构建函数construction,构造函数是专门用来创建对象的函数

使用typeof检查一个对象时,返回Object

在对象中保存的值称为属性

向对象添加属性

语法:对象.属性名=属性值;

读取对象中的属性

语法:对象. 属性名

如果读取对象中没有的属性,不会报错只会返回undefined

修改对象的属性值

语法: 对象.属性名 = 新值;

删除对象属性

语法: delete 对象.属性名

var obj=new Object()
//向Obj中添加一个name
obj.name="孙悟空";
//向obj中添加一个gender属性
obj.gender="男";
//向obj中添加一个age
obj.age=18;
console.log(obj);
属性名和属性值

向对象中添加属性

属性名:

​ 对象的属性名不强制要求准守标识符的规范

​ 所有的名字都可以用;但是我们使用时尽量遵循标识符的规范。

如果要是有特殊的属性名,不能采用.的方式来操作

需要另一种方式:

​ 语法:对象[“属性名”] = 属性值;读取是也要采用这样的方式

使用[]这种形式去操作属性,更加的灵活;在[]中可以直接传递一个变量,这样变量值是多少就会读取那个属性

var obj = new Object();
obj.name = "孙悟空";
obj var = "hello";
console.log(obj.var);
obj ["123"]="你好";
var n="nihao";
console.log(obj[n]);
//创建另一个对象
var obj2=new Object();
obj2.name = "猪八戒";
//将obj2设置为obj的属性值
obj.test=obj2;
console.log(obj.test.name);

属性值

JS对象的属性值,可以是任意的数据类型;甚至可以也是一个对象

in运算符

通过该运算符可以检查对象中是否有指定的属性;如果有返回true,没有则返回false。

语法:”属性名“ in 对象

基本和引用数据类型

基本数据类型:string number Boolean null undefined

引用数据类型:object

var a=123;
var b=a;
a++;
console.log(a);
console.log(b);
var obj=new Object();
obj.name="孙悟空";
var obj2=obj;
//修改obj的name属性
obj.name="猪八戒";
console.log(obj.name);
console.log(obj2.name);
//设置我obj2为null
console.log(obj);//不改变
console.log(obj2);//null
var c=10;
var d=10;
console.log(c==d);//true
var obj3="沙和尚”;
var obj4="沙和尚";
console.log(obj3==obj4);//false

JS中的变量都是保存在栈内存中的,基本数据类型直接再栈内存中存储;值与值之间是独立存在的,修改一个变量不会影响其他变量。

对象是保存在堆内存中的,每创建一个新的对象,就会开辟一个新的空间,而变量保存多是对象的内存地址(对象的引用)。如果两个变量保存的是同一个对象引用,当一个对象改变时另一个也受影响。

当比较基本数据类型时,就是比较值;当比较两个引用数据类型时,他比较的是内存地址,如果两个对象一模一样,但是地址不同也会返回false。

对象字面量
//创建一个对象
var obj=new Object();
//使用对象字面量来创建一个对象
var obj={};
console.log(obj);
obj.name="孙悟空";
var obj2={name:"猪八戒";};
console.log(obj2);

使用对象字面量,可以在创建对象时,直接指定对象中的属性

语法:{属性名:属性值;。。。}

字面量的属性名可以加引号也可以不加(建议不加)。

如果使用特殊的名字必须加引号。

属性名和属性值是一组一组的明智对结构

名和值之间使用:连接、多个名值对之间使用,隔开如果一个属性之后没有其他属性了,就不要写。

函数

函数也是一个对象;

函数中可以封装一些功能(代码),在需要时可以执行这些功能(代码)

函数可以保存一些代码在需要的时候调用。

//创建一个函数对象
//可以将要封装的对象以字符串的形式传递给结构函数
var fun=new Function("console.logz('hello 这是我的第一个函数');");
//console.log(fun);
//封装在函数中的代码不会立即执行;函数中的代码会在函数调用时执行
//调用函数语法,函数对象()
//当调用函数时,函数中封装的代码会按顺序执行
fun();


function fun2(){
    console.log("这是我的函数~~");
}
//console.log(fun2);
//调用fun2
fun2();
var fun3=function(){
    console.log("我是匿名函数封装的函数");
}fun3();

我们在实际开发中很少使用构造函数来创建一个函数对象

使用函数声明来创建一个函数

语法:

function函数名([形参1,形参2,形参3.。。形参N]){

语句。。。

}

函数表达式来创建一个函数

var 函数名=function([[形参1,形参2,形参3.。。形参N]){

语句。。。

}

函数的参数

定义一个用来两个数和的函数

可以在函数的()中指定一个或多个形参(形式参数)

多个形参之间,隔开,声明形参就相当于在函数内部声明了对应的变量,但是并不赋值。

function fun(a,b){
    //var a=prompt("");
    //var b=prompt("");
    console.log(a+b);
}
sum(1,2);

在调用函数时可以指定实参,实参将会赋值给对相应的形参。

调用函数时解析器不会检查实参的类型;所有要注意,是否可能接收非法的参数,如果有可能则需要对参数进行类型的检查。函数的实参可以任意的数据类型。

调用函数时,解析器也不会检查实参的数量;多余的实参不会被赋值;如果实参的数量小于形参的数量,则没有对应实参的形参就返回undefined

返回值

可以使用return来设置函数的返回值

语法:

​ return 值;

return后面的值将会作为函数的执行结果返回,可以定义一个变量来决定值

在函数中return后面的语句都不执行。

如果return语句后面不跟值相当于返回undefined;如果函数中不写return,则会返回undefined。

return后可以跟任意类型的值

//创建一个函数,用来计算三个数的和
function sum(a,b,c){
    //alert(a+b+c);
    var d=a+b+c;
    return d;
    return  ;=return undefined;
}
//调用函数
//变量result的值就是函数的执行结果
//函数返回什么result的值就是什么
ver result=sum(2,4,6);
console.log(result);//12


//例题
//定义一个函数,判断一个数字是否是偶数,如果是返回true,如果不是返回false
function isOu(num){
  // if(num%2==0){
    //   return true;
  // }else{
   //    return false;
  // }
    return num%2==0;
}
var result=isOu(2);
console.log(result);

//定义一个函数,可以根据半径计算一个圆的面积,并返回计算结果
//3.14*r*r
function mianJi(r){
    return 3.14*r*r;
}result=mianJi(10);
console.log("result"+result);
//创建一个函数,可以在控制台中输出一个人的信息,可以输入的name age gender address
function sayHello(o){
    console.log("我是"+o.name+",今年我"+o.age+"岁了,"+"我是一个"+o.gender+"人"+",我在在"+o.address);
}
//sayHello("孙悟空",18,"男","花果山");
//创建一个对象
var obj={
    name:"孙悟空",
    age:18,
    gender:"男",
    address:"花果山"
};
sayHello(obj);

function fun(a){
    console.log("a="+a);
   // a(obj);
}
//fun(sayHello);
//fun(function(){alert("hello")});
fun(mianji(10));//调用返回值

实参可以是任意的数据类型,也可以是一个对象;当我们的参数过多时,可以将参数封装到一个对象中,然后通过对象传递。

实参可以是一个对象,也可以是一个函数。

mianji() 调用函数:相当于使用函数的返回值

mianji 函数对象:相当于直接使用函数对象

return
function fun(){
    alert("函数要执行了~~");
    for(var i=0;i<5;i++){
        console.log(i);
        if(i==2){
            //break;
            //使用break退出循环
            //跳过当次循环
           // continue;
            //使用return可以结束这个函数
            //return;
        }
    }
    alert("函数要执行完了~~");
}
fun();
//返回值可以是任意类型,也可以是一个对象,也可以是函数
function fun2(){
    var obj= {name:"沙和尚"};
    return obj;
}
vat a=fun2();
console.log("a="+a.name);

function fun3(){
    function fun4(){
        //返回fun4函数对象作为返回值返回
        return fun4();
    }
}
a=fun3();
console.log(a);
立即执行函数

立即执行函数:函数执行完立即被调用;立即执行函数只会执行一次。

//函数对象
(function(){
    alert("我是一个匿名函数~~");
})();
(function(a,b){
    console.log(a);
     console.log(b);
})(233,432);
对象补充
//创建一个对象
var obj=new object();
//想对象中添加属性
obj.name="孙悟空";
obj.age=18;
//对象的属性可以是任意数据类型,也可以是函数
obj.sayName=function(){
    console.log(obj.name);
};
//console.log(obj.sayName);
//调方法
obj.sayName();
//调函数
fun();

var obj2(){
    name:"";
    age:18;
    sayName:function(){
        console.log(obj2.name);
    }
};
obj2,sayName();

函数也可以称为对象的属性,如果一个函数作为一个对象的属性保存,那么我们称这个函数时这个对象的方法;调用函数就说调用对象的方法(method)。

但是他们只是名称上有区别,其他的没有区别。

枚举对象中的属性

使用for…in语句

语法:

for(var 变量 in 对象){

}

for…in语句对象中有几个属性,所有在循环中就执行几次。每次执行时会将属性的名字赋值给变量。

var obj={
    name:"孙悟空",
    age:18,
    gender:"男",
    address:"花果山"
}
document.write();

for(var n in obj){
    //console.log("hello");
    console.log("属性名:"+n);
    console.log("属性值"+obj[n]);
}
作用域(Scope)

作用域:指一个变量作用的范围

在JS中有两种作用域:

1.全局作用域: 直接编写在script标签中的JS代码,都在全局作用域。

​ 全局作用域在页面打开时创建,在页面关闭时销毁

​ 在全局作用域中,有全局对象window(代表浏览器窗口),我 们可以直接使用。

​ 在全局作用域中:

​ 创建的变量都会作为window对象的属性保存;

​ 创建的函数会作为window对象的方法保存

function fun(){
    var a=123;
}
fun();
console.log(a);
var a=10;
console.log(window.a);
function fun(){
    console.log("我是fun函数");
}
window.fun();
变量的声明

变量的声明提前:使用var关键字的变量,会在所有代码执行之前被声明。;但是如果声明变量时不使用var关键字,则变量不会被提前声明。

函数声明提前:使用函数声明形式创建一个函数function 函数(){}他会在所有代码执行之前被创建,所有我们可以在函数声明前调用函数。

使用函数表达式创建的函数,不会被声明提前,所以不能在声明前调用

全局作用域的变量都是全局变量,在页面的任意位置都可以访问的到

//console.log("a="+a);
//var a=123;
fun();
//函数声明,会被提起前创建
function fun(){
    console.log("我是一个fun函数");
}
//函数表达式,不会被提前创建
var fun2 = function(){
    console.log("我是ufn2函数");
}
//fun2();
函数作用域

函数作用域:调用函数时创建函数作用域,函数执行完毕后,函数作用域催毁;

每调用一次函数作用域都会创建一个新的函数作用域,它们之间是互相独立的.

在函数作用域中可以访问到全局作用域的变量。在全局作用域中无法访问到函数作用域无法访问到函数作用域的变量。

当函数作用域操作一个变量时,他会先在自身作用域中寻找,如果有就直接使用,如果没有就在上一级中寻找。直到找到全局作用域。如果全局作用域依然没有找到,则会报错ReferenceError。

在函数中如果要访问全局变量,可以使用window对象。

在函数作用域也有什么提前的特性:使用var关键字声明的变量,会在函数中所有的代码执行之前声明。

函数声明也会在函数中所有代码执行之前执行。

//创建一个变量
var a=10;
function fun(){
    var a = "我是函数中的a";
    var b=20;
    console.log("a="+a);
    function fun()
}
fun();
fun();
console.log("b="+b);
    function fun3(){
        console.log(a);
        var a=10;
    }
var c=33;
    function fun5(){
        console.log("c");
        var c=20;
        //d没有使用var 关键字,则会设置为全局变量。
        d=100;
    }
    fun5();
    //在全局输出c
    console.log("c="+c);
    
    var e=23;
    function fun6(e){
        alert(e);
    }
    fun6();

在函数中,不使用var 声明的变量都是全局变量。

定义形参相当于在作用域中声明了变量

debug
alert(d);
var a=10;
var b="hello";
c=true;
function fun(){
    alert("hello");
}
vard=35;
this

解析器在调用函数每次都会想函数内部传递进一个隐含的参数。

这个隐含的参数就是this。

this指向的是一个对象,这个对象我们称为函数执行的上下文对象,根据函数的调用方式的不同,this会执行不同的对象。

  1. 以函数的形式调用时,this永远是window。
  2. 以方法的形式调用时,this就是调用方法那个对象。
function fun(a,b){
 //   console.log("a="+a,"b="+b);
    console.log(this.name);
}
var name="ell";
//fun(123,432);
var obj={
    bame:"孙悟空",
    sayName:fun
};
//console.log(obj.sayName == fun);
obj.sayName();
fun();
对象
function fun(){
    var obj =new Object();
    obj.name=name;
    obj.age=age;
    obj.gender=gender;
    obj.sayName=function(){
        console.log(this.name);
    }
    return obj;
}
var obj2=fun("孙悟空",28,"男");
console.sayName(obj2);

使用工厂的方法创建对象:通过该方法大批量的创建对象

使用工厂创建的对象都是Object,都是Object型。

创建一个构造函数,专门用来构建Person对象的 ;构造函数就是一个普通的函数,创建方式和普通函数没什么区别,不同的是构造函数习惯上首字母大写

构造函数与普通函数的区别就是调用方式不同

普通函数是直接调用,构造函数需要使用new关键字来调用。

执行流程:1.立刻创建一个新的对象

​ 2.将新创建的对象设置为函数中的this,在构造函数中可以使用this来引用新建对象。

​ 3.逐行执行函数中的代码

​ 4.将新的对象作为返回值返回

使用同一个构造函数创建的对象,我们称为一类对象。也将一个构造函数成为一个类

function Person(){
    //alert("hello");
    this.name="孙悟空";
}
var per=new Person();
console.log(per);

使用instanceof可以检查一个对象是否是一个类的实例。

语法: 对象 instenceof 构造函数

如果是 true 不是false.

所有的对象Object后代,所以任何对象跟它检查时都是true。

this的情况:

1.当以函数的形式调用时,this就是window

2.当以方法的形式调用时,谁调用方法this就是谁。

3.当以构造函数的形式调用时,this就是新创建的那个对象。

构造函数补充

在Person构造函数中,为每个对象都添加了一个sayName方法;

目前我们的方法是在构造函数内部创建时,也就是构造函数每执行一次就会创建一个新的sayName方法,也就是所有的sayName都是唯一的。

这样就导致了构造函数执行一次就创建一个新的方法。

执行1000次就创建1000个构造方法,而1000个一模一样方法完全是没有必要的。我们完全可以使用同一个方法。

//创建一个Person构造函数
function Person(name,age,gender){
    this.name = name;
    this.age=age;
    this.gender=gender;
    //想对象中添加一个元素
    this.sayName=fun;

}
//将函数定义在全局作用域,污染了全局作用域的命名空间
//而且定义在全局作用域中很不安全
function fun(){
        alert("hello大家好,我是"+this.name);};
//创建一个person的实例
var per=new Person("孙悟空",18,"男");
原型

原型prototype

我们所创建的每一个函数,解析器都会向函数中添加一个属性prototype

这个属性对应这一个对象,这个对象就是我们所谓的原型对象。

如果函数作为普通函数调用prototype没有任何作用

当函数以构造函数的形式调用时,他所创建的对象中都有一个银行属性,指向该构造函数的原型对象。

指向构造函数的原型对象,我们可以通过__proto__来访问该属性。

function Person(){
    
}
function MyClass(){
    
}
//向MyClass对象添加属性a
MyClass.prototype.a=123;
//向MyClass的原型中添加一个方法
MyClass.prototype.sayHello(){
    alert("hello");
}
var mc= new MyClass();
console.log(MyClass.prototype);
console.log(mc.__proto__ == MyClass.protoype);

原型对象就相当于一个公共的区域,所有同一个类的实力都可以访问到这个原型对象。

我们可以将对象中共有的内容统一设到原型对象中。

当我们访问对象的属性或方法时,他会现在对象自身中寻找,如果有则直接使用,如果没有会去原型对象中寻找。

以后我们创建构造函数时,可以将这些对象共有的属性方法,统一添加到构造函数的原型对象中。

这样不用分别为每一个对象添加,更不会影响到全局作用域,就可以是每一个对象都具有这些属相和方法了。

//创建一个构造函数
function MyClass(){
    
}
//向MyClass的原型对象中添加一个NAME属性
MyClass.prototype.name="我是原型对象中的名字";
var mc=new MyClass();
//console.log(mc.name);
//使用in检查对象中是否有某个属性是,如果对象中没有原型中有,也会返回true。
//console.log("name" in mc);
//可以使用对象的hasOwnProperty();来检查对象自身中是否有该属性
//使用该方法只有党对巷子深中含有属性时,不会返回true。
console.log(mc.hasOwnProperty("name"));

原型对象也是对象,所有他也有原型,当我们使用一个对象的属性或方法时,会先在自身中寻找,如果有则使用;如果没有则去原型中寻找,如果原型中有就是用,如果没有就去原型的原型中寻找,直到找到Object对象原型,Object对象的原型没有原型,如果在Object中依然没有找到,则返回undefined。

function Fun{
    var name=name;
    var age=age;
    var gender=gender;
}
//修改Person原型的toString
Person.prototype.toString = function(){
    return "Person[name="+this.name+",age="+this.age+",gender=]"
}
console.log(num);
//创建一个Fun实例
var num=new Fun("人",12,"男");
//当我们打印的对象是输出对象的toSring()方法的返回值时
//如果我们都是在输出对象时不输出[object,Object],可以为对象添加一个toString()方法
//只能修改一个对象 不提倡
//num.toString=function(){
  //  return "我是方法";
//}
var result = per.toString();
console.log("result"+result);
垃圾回收

人们生活中,时间一长就会产生垃圾,程序也一样,时间长了也会产生垃圾,这些垃圾积攒过多以后,会导致程序运行的速度过慢。所以我们需要一个垃圾回收的机制,来处理程序运行过程中产生的垃圾。

当一个对象没有任何的变量或属性对它进行引用,此时我们将永远无法操作该对象,此时这种对象就是一个垃圾,这种对象过多会占用大量的内存空间,导致程序运行变慢。所以这种垃圾需要进行清理

在JS中拥有自动垃圾回收机制,会自动将这些垃圾对象从内存中销毁,我们不需要进行垃圾回收操作。

我们只需要将不需要的对象设置为null即可。

var obj=new Object();
//对对象进行操作
obj=null;
数组

内建对象、宿主对象、自定义对象

数组(Array) :数组也是一个对象;它和普通对象类似,也是用来存储一些值的,不同的是普通对象是使用字符串作为属性名的,而数组是使用数字来作为索引操作元素。

索引:从0开始的整数。

数组的存储性能比普通对象要好,在开发中我们经常使用数组来存储一些数据。

向数组中添加元素

语法:数组[索引] =值;

读取数组中的元素

语法:console.log(数组[索引]);

如果读取不存在的索引,他不会报错而是返回undefined

//创建对象
var arr =new Array();
//使用tyoeof检查一个数组时,会返回object
console.log(typeof arr);
//添加元素
arr[0]=10;
console.log(arr.length);
console.log(arr);
arr.length=10;
console.log(arr.length);
console.log(arr);

获取数组的长度

可以使用length属性来获取数组的长度(元素的个数)

语法:数组.length console.log(arr.length);

对于连续的数组,使用length可以获取到数组的长度(元素的个数)

对于非连续的数组,使用length会获取到数组最大的索引+1;尽量不要创建非连续的数组

修改length

如果修改的length大于原长度,则多出部分会空出来。

如果修改的length小于原长度,则多出的元素会被删除。

向最后一个位置添加元素

语法:数组[数组.length]=值;

arr[arr.length]=70;

创建字面量数组

创建一个数组var arr=new Array();这样的方法比较麻烦,所有我们通常使用字面量数组

使用字面量数组 语法:[ ]

var arr=[ ];

使用字面量数组时,可以同时创建指定数组的元素

var arr=[1,2,4,5,7];

使用构造函数创建数组时,也可以同时添加元素,将添加的元素作为构造函数的参数传递

元素之间用逗号分隔var arr=new Array(19,20,34);

当创建一个只有一个数的值时用字面量arr=[10];

而为构造函数的数组会显示长度为10arr=new Array;

数组元素可以方任意类型的数据类型,也可以是字符串,也可以是一个函数,也可以是数组。

数组的方法

push() 该方法可以向数组的末尾添加一个或多个元素,并返回数组的新的长度

​ 可以将要添加的元素作为方法的参数传递

​ 这样这些元素将会自动添加到数组的末尾

​ 该方法会将数组的长度作为返回值返回。

//创建数组
var arr=["孙悟空","沙和尚","猪八戒"];
var result=arr.push("唐僧","蜘蛛精");
console.log("result="result);

pop() 该方法可以删除数组的最后一个元素,并将删除的元素进行返回

var arr=["孙悟空","沙和尚","猪八戒"];
arr.pop();
console.log(arr);
arr.unshift("牛魔王");
console.log(arr);
arr.shift();

unshift() 向数组开头添加一个或多个元素,并返回新的数组长度

向前面增加新的元素,原元素的索引依次增加。

数组的遍历
//创建一个数组
var arr=["孙悟空","猪八戒","沙和尚"];
//遍历数组,就是把数组中的所有数取出来   i是index的第一个字母  习惯性用i。
for(var i=0;i<1arr.length;i++){
    console.log(arr[i]);
}
数组练习
var per =new Person("孙悟空",18);
var per2 =new Person("猪八戒",28);
var per3 =new Person("沙和尚",43);
var per4 =new Person("唐僧",44);
var per5 =new Person("二郎神",38);
//将这些对象放在一个数组中
var perArr=[per,per2,per3,per4,per5];
//console.log(perArr);
//创建一个函数,可以将perArr中满18周岁的Person返回出来,然后封装得到一个新的数组中返回
//arr 形参  要提取信息的数组
function getAdult(arr){
    //创建一个新数组
    var newArr=[];

    //遍历arr,获取arr中Person对象
    for(var i=0;i<arr.length;i++){
        var p=arr[i];
        //判断Person对象的age是否大于等于18
       if(p.age>=18){
             //如果大于等于18,则将这个对象返回newArr中
            //将对象放入到新数组中
            newArr.push(p);
       }
    }
    //建新数组返回
    return newArr;
 
}
var arr1=getAdult(newArr);
console.log(arr1);
forEach

一般我们都是使用for循环去遍历数组,JS中还为我们提供了一个方法,用来遍历数组

forEach( ) 这个方法只支持IE8以上的浏览器;IE8以下的方法不支持该方法以下的方法尽量不要用。

//创建一个数组
var arr=["孙悟空","猪八戒","沙和尚"];
arr.forEach(function(a,b,c){
 console.log("a="+a);   
});

forEach( )方法需要一个函数作为参数

像这种函数,有我们创建但是不由我们调用的,我们称为回调函数。

数组中有几个元素,函数就执行几次;每次执行时,浏览器会将遍历到的元素以实参的形式传递。我们可以来定义形参来读取内容

浏览器会在回调函数中传递三个参数:第一个参数(遍历的元素)、第二个参数(当前正在遍历的索引)、第三个参数(正在遍历的数组)

slice()

可以用来从数组中提取需要的元素。

参数

该方法不会改变原数组,

  1. 截取开始的位置,包括开始索引
  2. 截取结束的位置,不包含结束索引

第二个参数可以不写,此时会截取索引往后的所有参数

索引值可以穿一个负值,则从后往前计算

-1倒数第一个

-2倒数第二个

var arr=["孙悟空","猪八戒","沙和尚"];
arr.slice(0,2);
console.log(arr);
splice()

可以用于删除数组中的指定元素 使用splice()会影响原数组,会将制定元素从原数组中删除;并将被删除的元素作为返回值返回。

参数:

  1. 表示开始位置的索引
  2. 表示删除的数量
  3. 可以传递一些新的元素,这些元素将会自动插入到开始的位置索引前面
arr.splice(0,2,"牛魔王");
console.log(arr);
//返回值
console.log(result);
练习
   //创建一个数组
        var arr = [1, 2, 3, 2, 1, 3, 4, 2, 5];
        // var arr1 = [];
        // //去重
        // for (var i = 0; i < arr.length; i++) {
        //     if (arr1.indexOf(arr[i]) == -1) {
        //         arr1.push(arr[i]);
        //     }
        // }
        // console.log(arr1);
        //获取数组中的每一个元素
        for (var i = 0; i < arr.length; i++) {
            console.log(arr[i]);
            /* 获取当前元素后的所有元素 */
            for (var j = i + 1; j < arr.length; j++) {
                //判断两个元素的值是否相等
                if (arr[i] == arr[j]) {
                    //如果相同就删j
                    arr.splice(j, 1);
                    //当删除j这个元素以后,后面的元素会自动补位 此
                    //事将不会比较这个元素, 我需要在比较一次j所在位置的元素
                    //使j自减
                    j--;
                }
            }
        }
        console.log(arr);
concat()

concat()可以链接两个或多个数组,并将新的数组返回

该方法不会对原数组产生影响

var arr=["孙悟空","猪八戒","沙和尚"];
var arr2=["唐僧","白骨精","蜘蛛精"];
var arr3=["二郎神","玉皇大帝","红孩儿"];
var result=arr.concat(arr2,arr,"牛魔王");
console.log(result);
join()

该方法可以将数组转换为一个字符串

该方法不会对原数组产生影响,而是将转换后的字符串作为结果返回

在join()中可以指定一个字符串作为参数,这个字符串将会称为数组中的元素的连接符。

如果不指定连接符,则默认,链接。

var arr=["孙悟空","猪八戒","沙和尚"];
result=arr.join(" ");
console.log(result);
reverse()

该方法用来反转数组(前面的去后面,后面的去前面)

该方法会直接修改原数组

var arr=["孙悟空","猪八戒","沙和尚"];
arr.reverse();
console.log(arr);
sort()

可以用来对数组中的元素进行排序

也会影响原数组,默认会按照Unicode编码进行排序

即使对于纯数字的数组,使用sort( )排序时,也会按照Unicode编码来排序

所以对数字排序时,可能会得到错误的结果。

我们可以自己来指定排序的规则

我们可以在sort()添加一个回调函数,来指定排序规则

回调函数中需要定义两个形参

浏览器将会分别使用数组中的元素作为实参去调用回调函数

使用那个元素调用不确定,但是肯定的是在数组中a一定在b的前面

浏览器会根据回调函数的返回值来决定元素的顺序

如果返回值为1 则降序排列 ;如果返回值为-1或0则升序排列

如果返回升序排列则返回a-b

如果返回降序排列则返回b-a

var arr=["孙悟空","猪八戒","沙和尚"];
arr.sort(function(a,b){
    //return 0;
    //升序排列
    return a-b;
    //降序排列
    return b-a;
});
console.log(arr);

一、内置对象

1.1 内置对象

内置对象就是指 JS 语言自带的一些对象,提供了一些常用的属性和方法,作用是帮助我们快速开发

JavaScript 提供了多个内置对象:Math、 Date 、Array、String等	

1.2 Math对象

属性、方法名功能
Math.PI圆周率
Math.floor()向下取整
Math.ceil()向上取整
Math.round()四舍五入版 就近取整 注意 -3.5 结果是 -3
Math.abs()绝对值
Math.max()/Math.min()求最大和最小值
Math.random()获取范围在[0,1)内的随机值
注意:上面的方法使用时必须带括号

**获取指定范围内的随机整数**:
function getRandom(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min; 
}

1.3 日期对象

  • 使用Date实例化日期对象

    • 获取当前时间必须实例化:
    var now = new Date();
    
    • 获取指定时间的日期对象
    var future = new Date('2019/5/1');
    

    注意:如果创建实例时并未传入参数,则得到的日期对象是当前时间对应的日期对象

    使用Date实例的方法和属性

1.png

  • 通过Date实例获取总毫米数

    • 总毫秒数的含义

      基于1970年1月1日(世界标准时间)起的毫秒数

    • 获取总毫秒数

      // 实例化Date对象
      var now = new Date();
      console.log(date.getTime())或者下面的方法	
      var now = + new Date();			
      

1.4 数组对象

1.4.1 创建数组的两种方式

  • 字面量方式

    示例代码如下:

    var arr = [1,"test",true];
    
  • new Array()

    示例代码如下:

    var arr = new Array();
    
    注意:上面代码中arr创建出的是一个空数组,如果需要使用构造函数Array创建非空数组,可以在创建数组时传入参数
    
    参数传递规则如下:
    - 如果只传入一个参数,则参数规定了数组的长度
    - 如果传入了多个参数,则参数称为数组的元素
    

1.4.2 检测是否为数组

  • instanceof 运算符

    instanceof 可以判断一个对象是否是某个构造函数的实例

    var arr = [1, 23];
    var obj = {};
    console.log(arr instanceof Array); // true
    console.log(obj instanceof Array); // false
    
  • Array.isArray()

    Array.isArray()用于判断一个对象是否为数组,isArray() 是 HTML5 中提供的方法

    var arr = [1, 23];
    var obj = {};
    console.log(Array.isArray(arr));   // true
    console.log(Array.isArray(obj));   // false
    

1.4.3 添加删除数组元素的方法

  • 数组中有进行增加、删除元素的方法,部分方法如下表

2.png

注意:push、unshift为增加元素方法;pop、shift为删除元素的方法

1.4.4 数组排序

  • 数组中有对数组本身排序的方法,部分方法如下表 3.png

    注意:sort方法需要传入参数来设置升序、降序排序

    • 如果传入“function(a,b){ return a-b;}”,则为升序
    • 如果传入“function(a,b){ return b-a;}”,则为降序

1.4.5 数组索引方法

  • 数组中有获取数组指定元素索引值的方法,部分方法如下表

4.png

1.4.6 数组转换为字符串

  • 数组中有把数组转化为字符串的方法,部分方法如下表

5.png

注意:join方法如果不传入参数,则按照 “ , ”拼接元素

1.4.7 其他方法

  • 数组中还有其他操作方法,同学们可以在课下自行查阅学习

6.png

1.5 字符串对象

1.5.1 根据字符返回位置

字符串中返回指定字符的位置的方法:

7.png

	案例:查找字符串"abcoefoxyozzopp"中所有o出现的位置以及次数
  1. 先查找第一个o出现的位置
  2. 然后 只要indexOf 返回的结果不是 -1 就继续往后查找 . 因为indexOf 只能查找到第一个,所以后面的查找,利用第二个参数,当前索引加1,从而继续查找

1.5.2 根据位置返回字符

字符串通过基本包装类型可以调用部分方法来操作字符串,以下是根据位置返回指定位置上的字符:

图片8.png

	在上述方法中,charCodeAt方法返回的是指定位置上字符对应的ASCII码,ASCII码对照表如下:

图片9.png

	案例:判断一个字符串 'abcoefoxyozzopp' 中出现次数最多的字符,并统计其次数
  1. 核心算法:利用 charAt() 遍历这个字符串

  2. 把每个字符都存储给对象, 如果对象没有该属性,就为1,如果存在了就 +1

    . 遍历对象,得到最大值和该字符

    注意:在遍历的过程中,把字符串中的每个字符作为对象的属性存储在对象总,对应的属性值是该字符出现的次数
    

1.5.3 字符串操作方法

图片10.png

1.5.4 replace()方法

replace() 方法用于在字符串中用一些字符替换另一些字符,其使用格式如下:

字符串.replace(被替换的字符串, 要替换为的字符串);

1.5.5 split()方法

	split()方法用于切分字符串,它可以将字符串切分为数组。在切分完毕之后,返回的是一个新数组。

	其使用格式如下:
字符串.split("分割字符")

二、 简单数据类型和复杂数据类型

2.1 简单数据类型

	**简单类型**(**基本数据类型**、**值类型**):在存储时变量中存储的是值本身,包括string ,number,boolean,undefined,null

2.2 复杂数据类型

	**复杂数据类型(引用类型)**:在存储时变量中存储的仅仅是地址(引用),通过 new 关键字创建的对象(系统对象、自定义对象),如 Object、Array、Date等;

2.3 堆栈

  • 堆栈空间分配区别:

1、栈(操作系统):由操作系统自动分配释放存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈;简单数据类型存放到栈里面

2、堆(操作系统):存储复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。

图片11.png

  • 简单数据类型的存储方式

    值类型变量的数据直接存放在变量(栈空间)中

图片12.png

  • 复杂数据类型的存储方式

    引用类型变量(栈空间)里存放的是地址,真正的对象实例存放在堆空间中

图片13.png

2.4 简单类型传参

	函数的形参也可以看做是一个变量,当我们把一个值类型变量作为参数传给函数的形参时,其实是把变量在栈空间里的值复制了一份给形参,那么在方法内部对形参做任何修改,都不会影响到的外部变量。
function fn(a) {
    a++;
    console.log(a); 
}
var x = 10;
fn(x);
console.log(x);
	运行结果如下:

图片14.png

2.5 复杂数据类型传参

	函数的形参也可以看做是一个变量,当我们把引用类型变量传给形参时,其实是把变量在栈空间里保存的堆地址复制给了形参,形参和实参其实保存的是同一个堆地址,所以操作的是同一个对象。
function Person(name) {
    this.name = name;
}
function f1(x) { // x = p
    console.log(x.name); // 2. 这个输出什么 ?    
    x.name = "张学友";
    console.log(x.name); // 3. 这个输出什么 ?    
}
var p = new Person("刘德华");
console.log(p.name);    // 1. 这个输出什么 ?   
f1(p);
console.log(p.name);    // 4. 这个输出什么 ?  
	运行结果如下:

mg-bkt5GQAf-1634029094236)]

注意:sort方法需要传入参数来设置升序、降序排序

  • 如果传入“function(a,b){ return a-b;}”,则为升序
  • 如果传入“function(a,b){ return b-a;}”,则为降序

1.4.5 数组索引方法

  • 数组中有获取数组指定元素索引值的方法,部分方法如下表

[外链图片转存中…(img-vEUlQagp-1634029094238)]

1.4.6 数组转换为字符串

  • 数组中有把数组转化为字符串的方法,部分方法如下表

[外链图片转存中…(img-YTpndMRc-1634029094239)]

注意:join方法如果不传入参数,则按照 “ , ”拼接元素

1.4.7 其他方法

  • 数组中还有其他操作方法,同学们可以在课下自行查阅学习

[外链图片转存中…(img-3WAguoPe-1634029094240)]

1.5 字符串对象

1.5.1 根据字符返回位置

字符串中返回指定字符的位置的方法:

[外链图片转存中…(img-wpBVWV8j-1634029094241)]

	案例:查找字符串"abcoefoxyozzopp"中所有o出现的位置以及次数
  1. 先查找第一个o出现的位置
  2. 然后 只要indexOf 返回的结果不是 -1 就继续往后查找 . 因为indexOf 只能查找到第一个,所以后面的查找,利用第二个参数,当前索引加1,从而继续查找

1.5.2 根据位置返回字符

字符串通过基本包装类型可以调用部分方法来操作字符串,以下是根据位置返回指定位置上的字符:

[外链图片转存中…(img-mgjZYFki-1634029094242)]

	在上述方法中,charCodeAt方法返回的是指定位置上字符对应的ASCII码,ASCII码对照表如下:

[外链图片转存中…(img-evlvrQhA-1634029094243)]

	案例:判断一个字符串 'abcoefoxyozzopp' 中出现次数最多的字符,并统计其次数
  1. 核心算法:利用 charAt() 遍历这个字符串

  2. 把每个字符都存储给对象, 如果对象没有该属性,就为1,如果存在了就 +1

    . 遍历对象,得到最大值和该字符

    注意:在遍历的过程中,把字符串中的每个字符作为对象的属性存储在对象总,对应的属性值是该字符出现的次数
    

1.5.3 字符串操作方法

[外链图片转存中…(img-iq4Wf9OJ-1634029094249)]

1.5.4 replace()方法

replace() 方法用于在字符串中用一些字符替换另一些字符,其使用格式如下:

字符串.replace(被替换的字符串, 要替换为的字符串);

1.5.5 split()方法

	split()方法用于切分字符串,它可以将字符串切分为数组。在切分完毕之后,返回的是一个新数组。

	其使用格式如下:
字符串.split("分割字符")

二、 简单数据类型和复杂数据类型

2.1 简单数据类型

	**简单类型**(**基本数据类型**、**值类型**):在存储时变量中存储的是值本身,包括string ,number,boolean,undefined,null

2.2 复杂数据类型

	**复杂数据类型(引用类型)**:在存储时变量中存储的仅仅是地址(引用),通过 new 关键字创建的对象(系统对象、自定义对象),如 Object、Array、Date等;

2.3 堆栈

  • 堆栈空间分配区别:

1、栈(操作系统):由操作系统自动分配释放存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈;简单数据类型存放到栈里面

2、堆(操作系统):存储复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。

[外链图片转存中…(img-THD9bBfk-1634029094252)]

  • 简单数据类型的存储方式

    值类型变量的数据直接存放在变量(栈空间)中

[外链图片转存中…(img-WM8pPumC-1634029094253)]

  • 复杂数据类型的存储方式

    引用类型变量(栈空间)里存放的是地址,真正的对象实例存放在堆空间中

[外链图片转存中…(img-hKF09usy-1634029094254)]

2.4 简单类型传参

	函数的形参也可以看做是一个变量,当我们把一个值类型变量作为参数传给函数的形参时,其实是把变量在栈空间里的值复制了一份给形参,那么在方法内部对形参做任何修改,都不会影响到的外部变量。
function fn(a) {
    a++;
    console.log(a); 
}
var x = 10;
fn(x);
console.log(x);
	运行结果如下:

[外链图片转存中…(img-XSxLxwtM-1634029094255)]

2.5 复杂数据类型传参

	函数的形参也可以看做是一个变量,当我们把引用类型变量传给形参时,其实是把变量在栈空间里保存的堆地址复制给了形参,形参和实参其实保存的是同一个堆地址,所以操作的是同一个对象。
function Person(name) {
    this.name = name;
}
function f1(x) { // x = p
    console.log(x.name); // 2. 这个输出什么 ?    
    x.name = "张学友";
    console.log(x.name); // 3. 这个输出什么 ?    
}
var p = new Person("刘德华");
console.log(p.name);    // 1. 这个输出什么 ?   
f1(p);
console.log(p.name);    // 4. 这个输出什么 ?  
	运行结果如下:
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值