3. javaScript基础学习笔记(上)

1 初见js

1.alert() --警告框

2.document.write() --在计算机页面输出文本

3.console.log() --在计算机页面输出文本

2 js的编写位置

1.body里面

(1)标签onclick属性

例如:< button οnclick=“alert(‘讨厌’)”>按钮< /button>

(2)超链接的href属性

例如: < a href=“javascript:alert(‘你是谁’)”>点一下< /a>

2.script标签里面

例如:

< script type=“text/javascript”>alert(“我是标签代码”)< /script>
3.外部js文件

例如:

< script type=“text/javascript” src=“js/script.js”>

好处:将js代码写到外部js文件,通过script标签引入 。可以在不同页面中同时引入,也可以利用到浏览器的缓存机制。

3 基本语法

1.单行注释//

2.多行注释/**/

3.JS中严格区分大小写

4.JS中每条语句以分号(;)结尾

5.不写分号,浏览器会自动添加,但会消耗一定的系统资源,且浏览器可能会加错分号

6.JS会忽略多个空格和换行

4 字面量和变量

1.字面量

解析:是一些不可改变的值,可直接使用

例如:1 2 3 4

2.变量

解析:变量可保存字面量,变量的值是可随意改变

3.声明变量

解析:js使用var关键字来声明一个变量,声明和初始化同时进行

5 标识符

1.js中可以自主命名的都可以称之为标识符

例如:变量名、函数名、属性名

2.标识符中可以含有字母、数字、_、$

3.标识符不能以数字开头

4.标识符不能是ES中的关键字或者保留字

5.标识符一般使用驼峰命名:首字母小写,每个单词的开头字母大写,其余字母小写

6 数据类型

6.1 基本数据类型

String 字符串、Number 数字、Boolean 布尔值、 Null 空值、 Undefined 未定义、Symbol(ES6)

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

例如:

var a = 123;

var b = a;

a++;

console.log("a = "+a);//124

console.log("b = "+b);//123

6.2 引用数据类型

Object(在JS中除了基本数据类型以外的都是对象,数据是对象,函数是对象,正则表达式是对象)

  1. 对象是保存到堆内存中的,每创建一个新的对象,就会在堆内存中开辟出一个新的空间
  2. 变量保存的是对象的内存地址(对象的引用),如果两个变量保存的是同一个对象引用,当一个变量修改属性时,另一个也会受到影响

例如:

var obj = new Object();

obj.name = “孙悟空”;

var obj2 = obj;

obj.name = “猪八戒”;

console.log(obj.name);//猪八戒

console.log(obj2.name)//猪八戒

特殊:设置obj2为null,修改变量的值时候,另一个变量不受影响

数据类型比较

  1. 比较两个基本数据类型的值时,就是比较值
  2. 比较两个引用数据类型时,它是比较的对象的内存地址
  3. 引用类型,如果两个对象一摸一样,但是地址不同,返回false
6.3 String

1.字符串需要使用引号引起来;双引号或单引号都可,但不能混着用

2.引号不能嵌套,双引号不能放双引号,单引号不能使用单引号

例如正确做法: str = ‘我说:“喜欢你”’

3.字符串的转义字符

(1) \ " 表示 "

(2) \ ’ 表示 ’

(3) \n 表示 换行

(4) \t 表示 转表符

(5) \ \ 表示 \

6.4 Number

解析:JS中所有数值都使用number类型,包括整数和浮点数(小数)

1.Number.MAX_VALUE表示js中数字的最大值

2.Number.MIN_VALUE示js中数字的最小值

3.使用Number表示的数字超过了最大值,则返回Infinity,表示正无穷; -Infinity表示负无穷

4.NaN表示一个特殊的数字,表示 Not A Number,检查该值时返回Number

5.typeof运算符可检测变量的类型

语法:【typeof 变量】

6.JS进行浮点运算,结果可能不精确;不用JS进行对精确度要求高的运算

6.5 Boolean

解析:布尔值有两个,主要用来负责逻辑判断

true – 表示真

false --表示假

6.6 Null

解析:Null(空值)类型的值只有一个,那就是null

1.null这个值专门用来表示一个为空的对象

2.使用typeof检查null值时,会返回一个object

6.7 undefined

解析: Undefined(未定义)类型的值只有一个,那就是undefined

1.声明一个变量,但不给变量赋值时,他的值就是undefined

2.使用typeof检查undefined值时,会返回一个undefined

7 强制类型转换

解析:指将一个数据类型转换成其他数据类型;类型转换主要指将其他数据类型转成String、Number、Boolean

7.1 转换成String

方式一:toSting()

例如:a = a.toSting();

  1. 调用被转换的数据类型的toSting()方法
  2. 该方法不会影响到原变量,它会将被转换的结果返回
  3. null和undefined两个值是没有toString,如调用他们的方法会报错

方式二:String()

例如; a = String(a);

1.调用String()函数,并将被转换的数据作为参数传递给函数

2.用String()函数做强制类型转换:

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

​ -对null 和 undefined ,就不会调用toString()方法;它会将null直接转换城"null";它会将undefined直接转换城"undefined"

方式三:隐式类型转换–加法运算

解析:任何的值和字符串做加法运算,都会先转换成字符串,只需要为任意的数据类型+一个"",即可将其转换成string,由浏览器自动完成.

7.2 转换成Number

方式一:Number()

例如:a = Number(a);

字符串 转 数字

1.如果是纯数字的字符串,则直接转成数字

2.如果字符串中有非数字的内容,则转换成NaN

3.如果字符串是一个空串或者是一个全是空格的字符,则转成0

布尔值 转 数字

1.true 转 1

2.false 转 0

Null 转 数字 0

undefined 转 数字 NaN

方式二:parseInt()和 parseFloat()

解析:这种方式用来专门对付字符串

1.parseInt()把字符串中有效的整数内容取出来,然后转成number

例如:var a = “123px”;a = parseInt(a);//123

2.parseFloat()把一个字符串转成浮点数

例如; var a = “123.569px”; a = parseFloat(a);//123.569

3.非string使用parseFloat()或parseInt(),它会先转成string,然后再操作

方式三:隐式类型转换

解析:任何值做/ * - 运算,都会自动转换成Number;通过为一个值 -0 *1 /1 可将其转换为Number类型

方式四:一元运算+

解析:对非Number类型的值,会先转为Number,然后再运算;可对一个其他数据类型值使用+,可将其转换成number。

例如:var b = 1 + ‘2’ + 3; //123

​ var b = 1 + +‘2’ + 3; //6

7.3 其他进制数字表示
  1. 十六进制表示

解析:输入需要以0x开头;以10进制输出

例如:a = 0xa;//10

  1. 八进制表示

解析:0开头表示八进制;

例如: a = 070;//70

特殊:"070"这种字符串,有些浏览器会当成8进制解析,有些会当成10进制解析

解决:在parseInt()中传递一个第二个参数,来指定数字的进制

例如:a = parseInt(a,10);

  1. 二进制表示

解析: 0b开头便是二进制

例如: a = 0b10;//10

7.4 转换成Boolean

方式一:Boolean()

1.数字转成Boolean,除了0和NaN其他都是true

2.字符串转成Boolean,除了空串其他都是true

3.null转成Boolean,为false

4.undefined 转成Boolean,为false

8 算术运算符

解析:对非Number的值进行运算时,会将这些值转换成Number再进行运算(与String加法运算除外)

例如: result = 123 + ‘1’;//1231 String

​ result = true + 1; //2 number

​ result = 2 + null;//2 number

​ result = 2 + undefined;//NaN number

  1. 任何值和NaN进行任何运算都得NaN

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

2.如对两个字符串进行加法运算,会将两个字符串拼接为一个字符串,并返回.

例如:result = ‘你好’+ ‘帅哥’//你好帅哥

3.任何的值和字符串做加法运算,都会先转换成 字符串,然后再和字符串进行拼接操作

例如:

result = 123 + ‘1’;//1231 String

result = true + ‘nihao’;//truenihao String

/ * -

解析:减号可以对两个字符串进行减法运算,并将结果返回;乘号可以对两个字符串进行乘法运算,并将结果返回;除号可以对两个字符串进行除法运算,并将结果返回

1.任何值做/ * - 运算,都会自动转换成Number

%

解析:%去模运算(取余数);先转成数字类型再运算

例如:

b = 2 % ‘3’;//2

b = 2 % true;//0

b = 2 % null;//NaN

b = 2 % undefined;//NaN

b = 2 % NaN;//NaN

9 一元运算符

  1. +正号

解析:正号不会对数字产生任何影响

  1. -负号

解析: 负号可以对数字进行负号的取反

特殊:对非Number类型的值,会先转为Number,然后再运算

例如:var b = 1 + +‘2’ + 3; //6

10 自增和自减

10.1 自增

解析:通过自增可使变量在自身的基础上加1

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

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

a++ 和 ++a异同

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

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

10.2 自减

解析:通过自减可使变量在自身的基础上减1

1.自减分成两种:后–(a–)和 前–(--a),都会立即使原变量的值自减1

a-- 和 --a异同

  1. a–的值等于原变量的值(自减前的值)

  2. –a的值等于原变量的新值(自减后的值)

11 逻辑运算符

11.1 !非

解析:非运算就是对一个布尔值进行取反操作, true变false ,false变true

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

非布尔值的非运算

解析:对非布尔值进行非运算,则先会将其转换成布尔值,再进行取反

11.2 && 与

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

1.两个值都为true,结果才返回为true

2.只要有一个为false,就返回false

3.如果第一个值为false,则不会看第二个值

非布尔值的与运算

解析:对非布尔值进行与运算,会先将其转换成布尔值,然后再运算,并且返回原值

1.如果第一个值为true,则必然返回第二个值

2.如果二个值为false,则必然返回第一个值

11.3 || 或

解析:可以对符号两侧是值进行或运算并返回结果

1.两个值只要有一个值为true,就返回true

2.如果两个值都为false,则返回false

3.如果第一个值为true,则不会看第二个值

非布尔值的或运算

解析:对非布尔值进行或运算,会先将其转换成布尔值,然后再运算,并且返回原值

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

  1. 如果第一个值是false,则直接返回第二个值

12 赋值运算符

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

  1. a += 5 等价于a = a+5

  2. a -= 5 等价于a = a-5

  3. a = 5 等价于a = a5

  4. a /= 5 等价于a = a/5

13 关系运算符

解析:通过关系运算符可以比较值之间的大小关系;如关系成立它返回true,如关系不成立则返回false

1.非数值情况

解析:对于非数值进行比较时,会将其转换成数字然后进行比较

例如: console.log(1 > true);//false

​ console.log(1 >= true);// true

​ console.log(1 > “0”);//true

​ console.log(10 > null);//true

2.符号两侧是字符串

解析:如果符号两侧的值都是字符串时,不会将其转成数字比较

(1)比较两个字符串时,比较的是字符串的编码

例如:console.log(“a” < “b”); //true

(2)比较字符编码是一位一位进行比较;如两位一样,则比较下一位,可以用来对英文进行排序

例如:

console.log(“abc” < “b”);//true

console.log(“bbc” < “b”);//false

(3)如比较的这两个字符串的数字,可能会得到不可预期的结果

特殊:在比较两个字符串类型的数字时,必须要转型

例如:

console.log(“11” < +“5”);//false

14 编码

编码链接:unicode.org

1.在script里面

解析: 在字符串中使用转义字符例如Unicode编码

语法:【\u四位编码】

例如: console.log("\u2620");//骷颅头

2.在body里面

语法:【 &#编码; 】;这里使用的编码需要的是10进制

例如: < h1 style=“font-size: 200px;”>☠< /h1>

15 相等运算符

解析:相等运算符用来比较两个值是否相等,如果相等会返回true,否则返回false

15.1 ==

解析: == 用来做相等运算

  1. 使用==来比较时,如值的类型不同则会自动进行类型转换,将其转换成相同的类型再比较

  2. 一般转换成数字进行比较

例如:console.log(“1” == 1); //true

​ console.log(true == “1”); //true

  1. 也有不转成数字的

例如: console.log(null == 0); //false

  1. undefined衍生自null,两个值做相等判断时,返回true

例如: console.log(undefined == null); //true

  1. NaN不和任何值相等,包括它本身

​ console.log(NaN == NaN); //false

  1. 通过isNaN()函数可以判断一个值是不是NaN

var b = NaN;

​ console.log(isNaN(b)); //true

15.2 !=

解析: 不相等用来判断两个值是否不相等,如果不相等返回true,否则返回false;

  1. 使用!=来做不相等运算,会对变量进行自动的类型转换,如果转换后等于它也会返回false

例如:console.log(“1” != 1); //false

15.3 ===

解析:用来判断两个值是否全等,它和相等类似。不同的是它不做自动类型转换。如果两个值类型不同,直接fasle

例如: console.log(“123” === 123); //false

15.4 !==

解析:用来判断两个值是否不全等,它和不等类似。不同的是它不做自动类型转换。如果两个值类型不同,直接true

例如:console.log(‘1’ !== 1); //true

16 条件运算符

解析:条件运算符也叫三元运算符

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

  1. 条件运算符在执行时,首先对条件表达式进行求值

  2. 如果该值为true,则执行语句1,并返回执行结果

  3. 如果该值为false,则执行语句2,并返回执行结果

例如:获取a, b , c中最大的值

写法1:先获取a,b最大值;后获取a, b , c中最大的值

​ var max = a > b ? a : b;

​ max = max > c ? max : c;

写法二:阅读性差,不推荐使用

​ var max = a > b?(a > c ? a : c):(b>c ? b: c);

  1. 如条件表达式的求值结果不是一个布尔值,会将其转换为布尔值,然后再进行运算

例如: “hello” ? alert(“语句1”) : alert(“语句2”);

17 运算符的优先级

解析:在JS中有一个运算符优先级的表,在表中越靠上优先级越高,优先级越高越优先计算,如果优先级一样,则从左往右计算。

  1. 使用逗号可以分割多个语句,一般可以在声明多个变量时使用

例如:var a , b , c;

  1. 可以使用()来改变优先级

18 代码块

解析:JS中可以使用{}来为语句进行分组, 同一个{}中的语句为是一组语句,它们要么都执行,要么都不执行。

  1. 一个{}中的语句称为一个代码块

  2. 代码块的后边不再写【;】

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

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

19 流程控制语句

三类:

  1. 条件判断语句

  2. 条件分支语句

  3. 循环语句

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

19.1 条件判断语句

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

语法一:

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

  1. if语句在执行时,会先对条件表达式进行求值判断,如果条件表达式的值为true,则执行if后的语句;如果条件表达式的值为false,则不会执行if后的语句。
  2. if语句只能控制紧随其后的那个语句
  3. 如果希望 if 语句可以控制多条语句,可以将这些语句统一放到代码块中

语法二:

if(条件表达式){

语句…

}else{

​ 语句… }

  1. 当该语句执行时,会先对if后的条件表达式进行求值判断,如果该值为true,则执行if后的语句; 如果该值为false,则执行else后的语句

语法三:

if(条件表达式) { 语句…

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

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

}else{ 语句… }

  1. 当该语句执行时,会从上到下依次对条件表达式进行求值判断,如果值为true,则执行当前语句;如果值为false,则继续向下判断;如果所有的条件都不满足,则执行最后一个else后的语句
  2. 该语句中,只会有一个代码块被执行,一旦代码块执行了,则直接结束语句
19.2 条件分支语句

解析:执行时会依次将case后的表达式的值和switch后的条件表达式的值进行全等比较,如果比较结果为true,则从当前case处开始执行代码; 当前case后的所有的代码都会执行,我们可以在case的后边跟着一个break关键字, 这样可以确保只会执行当前case后的语句,而不会执行其他的case。如果比较结果为false,则继续向下比较;如果所有的比较结果都为false,则只执行default后的语句

语法:

switch(条件表达式){

​ case 表达式:

​ 语句…

​ break;

​ case 表达式:

​ 语句…

​ break;

​ default:

​ 语句…

​ break; }

19.3 循环–while

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

语法:

while(条件表达式){

​ 语句… }

19.4 循环–do…while

解析: do…while语句在执行时,会先执行循环体;循环体执行完毕以后,在对while后的条件表达式进行判断;如果结果为true,则继续执行循环体,执行完毕继续判断以此类推; 如果结果为false,则终止循环

语法:

do{

​ 语句… }while(条件表达式)

while循环和o…while循环区别

  1. while是先判断后执行
  2. 而do…while会先执行后判断,do…while可以保证循环体至少执行一次

死循环

解析:将条件表达式写死为true的循环,叫做死循环;该循环不会停止,除非浏览器关闭,死循环在开发中慎用

例如:while(true){ alert(n++); }

循环创建三步骤

  1. 创建初始化一个变量

    var i = 1;

  2. 设置一个条件表达式

    while(i <= 10){

  3. 定义一个更新表达式

document.write(i++ +" <br / >") }

19.5 循环–for

解析:for循环中,提供了专门的位置用来放三个表达式:

  1. 初始化表达式

  2. 条件表达式

  3. 更新表达式

语法: for(①初始化表达式;②条件表达式;④更新表达式){ ③语句… }

执行流程:

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

  2. ②执行条件表达式,判断是否执行循环。

  3. 如果为true,则执行循环③

  4. 如果为false,终止循环

  5. ④执行更新表达式,更新表达式执行完毕继续重复②

特殊:for循环中的三个部分都可以省略,也可以写在外部。如果在for循环中不写任何的表达式,只写两个;

此时循环是一个死循环会一直执行下去,慎用。

例如:

for(;; ){ alert(“hello”); }

嵌套for循环

语法:

for(){

for(){ }

}

  1. 外层for循环执行几次,图形的高度就是多少
  2. 内部循环,用来控制图形的宽度
19.6 prompt提示框

解析: prompt()可以弹出一个提示框,该提示框中会带有一个文本框,

  1. 用户可以在文本框中输入一段内容,该函数需要一个字符串作为参数,该字符串将会作为提示框的提示文字

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

例如: var score = prompt(“请输入小明的期末成绩(0-100):”);

20 break和continue

20.1 break

解析:break关键字可以用来退出switch或循环语句

  1. 不能在if语句中使用break和continue
  2. break关键字,会立即终止离他最近的那个循环语句

特殊:

for(var i=0 ; i<5 ; i++){

console.log("@外层循环"+i)

for(var j=0 ; j<5; j++){

​ break;

​ console.log(“内层循环:”+j);

}

} //结果是内层循环跳出了,外层循环还在执行

方案:为循环语句创建一个label,来标识当前的循环

语法: 【label:循环语句】;使用break语句时,在break后跟着一个label,break将会结束指定的循环,而不是最近的

例如:

outer:

for(var i=0 ; i<5 ; i++){

console.log("@外层循环"+i)

for(var j=0 ; j<5; j++){

​ break outer;

​ console.log(“内层循环:”+j);

} }

20.2 continue

解析: continue关键字用来跳过当次循环

  1. 同continue也是默认只会对离他最近的循环起作用
20.3 return

解析:return可以结束整个函数

21 对象

解析:除了基本数据类型,其他都属于对象

21.1 对象分类

内建对象:

  1. 由ES标准中定义的对象,在任何的ES的实现中都可以使用

例如:Math String Number Boolean Function Object…

宿主对象:

  1. 由JS的运行环境提供的对象,目前来讲主要指由浏览器提供的对象

例如: BOM(浏览器对象模型) DOM(文档对象模型)

自定义对象:

  1. 有开发人员创建的对象
21.2 对象的创建
  1. 使用new关键字调用的函数,是构造函数;构造函数是专门用来创建对象的函数;使用typeof检查一个对象时,会返回object

例如:var obj = new Object();

21.3 对象属性的添加

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

21.3.1 属性名:
  1. 对象的属性名不强制要求遵守标识符的规范,什么都可以,但是我们还是尽量按照标识符的规范去做

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

例如: obj.name = “孙悟空”;

特殊属性名:

  1. 不能采用.的方式来操作的特殊属性名,用另一种方式
  2. 语法:对象[“属性名”] = 属性值
  3. 读取也需要这种方式;[]这种形式去操作属性,更加的灵活

例如:

​ obj[“123”] = 789;

​ console.log(obj[“123”]); //789

21.3.2 属性值:
  1. JS对象的属性值,可以是任意的数据类型;对象也行,函数也行

对象属性的读取:

解析:读取对象的属性,有则返回;无则返回undefined,不会报错

语法:对象.属性名

例如: console.log(obj.name);

对象属性的修改

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

例如: obj.name = “tom”;

对象属性的删除

语法:delete 对象.属性名

例如: delete obj.name;

  1. 对象的属性值是函数的时候

解析:

  1. 如一个函数作为一个对象的属性保存,那这个函数是这个对象的方法
  2. 调用这个函数就说调用对象的方法(method)
  3. 它们只是名称上的区别,没有其他的区别

例如:

//对象的方法

obj.sayName = function () {

​ console.log(obj.name);

};

//调方法 什么点什么就是调用什么的方法,如下:

obj.sayName();

//函数

function fun() {

​ console.log(obj.name);

};

//调函数

fun();

21.4 枚举对象中的属性:

解析:

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

语法: for(var 变量 in 对象){ }

例如:

for (var n in obj) {

console.log(“属性名:” + n);

console.log(“属性值:” + obj[n]); //obj[n]表示该对应属性的值

}

21.5 in 运算符

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

语法:“属性名” in 对象

例如: console.log(“test2” in obj);

21.6 对象的字面量

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

语法:{属性名:属性值,属性名:属性值…}

  1. 对象字面量的属性名可以加引号也可以不加,建议不加
  2. 如果要使用一些特殊的名字,则必须加引号
  3. 属性名和属性值是一组一组的名值对结构
  4. 名和值之间使用:连接,多个名值对之间使用,隔开

例如;

var obj2 = {

name: “猪八戒”,

age: 13,

gender: “男”,

test: { name: “沙僧” }

};

22 工厂方法创建对象

解析: 使用工厂方法可以大批量的创建对象

22.1 方式一:解决了每创建一个对象都要创建一个函数问题

缺点:工厂方法创建的对象,使用的构造函数都是Object, 所以创建的对象都是Object这个类型,以至于无法区分出多种不同类型的对象

例如:

function createPerson(name, age, gender) {

//创建一个新的对象

var obj = new Object();

//向对象中添加属性

obj.name = name;

obj.age = age;

obj.gender = gender;

obj.sayName = function () {

​ alert(this.name);

};

//将新的对象返回

return obj;

}

22.2 方式二: 解决了多种不同类型的对象无法区分问题

解析:

  1. 创建一个构造函数,专门用来创建某某对象;

    –构造函数就是一个普通的函数,创建方式和普通函数没有区别;

    –不同的是构造函数习惯上首字母大写

  2. 构造函数和普通函数的区别就是调用方式的不同:

​ --普通函数是直接调用,

​ --构造函数需要使用new关键字来调用

  1. 构造函数的执行流程:

​ (1)立刻创建一个新的对象

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

​ (3)逐行执行函数中的代码

​ (4)将新建的对象作为返回值返回

  1. 同一个构造函数创建的对象,称为一类对象;

    –也将一个构造函数称为一个类;

    –将通过一个构造函数创建的对象,称为是该类的实例

  2. this的情况:

​ (1)当以函数的形式调用时,this是window

​ (2)当以方法的形式调用时,谁调用方法this就是谁

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

例如:

function Person(name, age, gender) {

this.name = name;

this.age = age;

this.gender = gender;

this.sayName = function () {

​ alert(this.name);

}; }

var per = new Person(“孙悟空”, 18, “男”);

console.log(per)

问题:Person构造函数中,每一个对象都添加了一个sayName方法。目前sayName方法构造函数内部创建,会造成构造函数每执行一次就会创建一个新的sayName方法,这样会影响性能。

解决一:

解析:将sayName方法在全局作用域中定义

例如:

function fun(){

alert(“Hello大家好,我是:”+this.name); };

缺点:将函数定义在全局作用域,污染了全局作用域的命名空间,而且定义在全局作用域中也很不安全

解决二:

解析:在原型中添加sayName方法

例如:

Person.prototype.sayName = function () {

alert(“Hello大家好,我是:” + this.name); };

优点:不用多次创建sayName方法,减低性能消耗

22.3 instanceof

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

语法:对象 instanceof 构造函数

例如:

console.log(per instanceof Person); //如果是,则返回true,否则返回false

  1. 所有的对象都是Object的后代,任何对象和Object进行instanceof检查时都会返回true

例如: console.log(dog instanceof Object); //true

23 函数

解析:

  1. 函数function也是一个对象;
  2. 函数中可以封装一些功能(代码),在需要时可以执行这些功能(代码);
  3. 函数中可以保存一些代码在需要的时候调用
  4. 使用typeof检查一个函数对象时,会返回function

函数创建

23.1 方法一:构造函数(实际开发中很少使用)

解析:将要封装的代码以字符串的形式传递给构造函数

例如:var fun = new Function(“console.log(‘Hello 这是我的第一个函数’);”);

  1. 封装到函数中的代码不会立即执行;会在函数调用的时候执行
  2. 当调用函数时,函数中封装的代码会按照顺序执行
  3. 语法:函数对象() 例如: fun()
23.2 方法二:函数声明(常用)

语法:

function 函数名([形参1,形参2…形参N]){ 语句… }

例如:

function fun2() {

​ console.log(“这是我的第二个函数~~~”);

​ alert(“哈哈哈哈哈”);

​ document.write("(>_<)");

​ }

fun2();

23.3 方法三:函数表达式

语法:

var 函数名 = function([形参1,形参2…形参N]){ 语句… };

例如:

var fun3 = function () {

​ console.log(“我是匿名函数中封装的代码”);

​ };

fun3();

23.4 函数的参数

解析:

  1. 函数的()中可以指定一个或多个形参(形式参数);多个形参之间使用逗号隔开,声明形参就相当于在函数内部声明了对应的变量,但是并不赋值

例如:function sum(a, b) { console.log(a + b); } === function* sum() { var a, b; console.log(a + b); }

  1. 函数的实参可以是任意的数据类型,对象,函数等

例如: sum(true , false);

  1. 在调用函数时,可以在()中指定实参(实际参数),实参将会赋值给函数中对应的形参

例如:sum(1,2);

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

  2. 调用函数时,解析器也不会检查实参的数量

​ ----多余实参不会被赋值

​ ----如果实参的数量少于形参的数量,则没有对应实参的形参将是undefined

23.5 函数的返回值

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

语法: 【return 值】

  1. return后的值将会作为函数的执行结果返回,可以定义一个变量,来接收该结果
  2. 如果return语句后不跟任何值就相当于返回一个undefined;
  3. 如果函数中不写return,则也会返回undefined
  4. 在函数中return后的语句都不会执行
  5. 返回值可以是任意的数据类型,对象、函数都行

例如:

function sum(a, b, c) {

var d = a + b + c;

return d; }

调用函数

例如:

  1. 变量result的值就是函数的执行结果
  2. 函数返回什么result的值就是什么

var result = sum(4, 7, 8);

23.6 函数的方法
23.6.1 call()和apply()

解析:

  1. 两个都是函数对象的方法,需要通过函数对象来调用
  2. 当对函数调用call()和apply()都会调用函数执行
  3. 在调用call()和apply()可以将一个对象指定为第一个参数,此时这个对象将会成为函数执行时的this

例如:function fun() {

alert(this.name);}

var obj = {name: “aa”,}

fun.call(obj);//aa

fun.apply(obj);//aa

call()和apply()区别

  1. call()方法可以将实参在对象之后依次传递

例如:function fun(a, b) {

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

console.log("b = " + b);}

var obj = {

name: “obj”,};

fun.call(obj,2,3);//a = 2, b = 3

  1. apply()方法需要将实参封装到一个对象后的数组中统一传递

例如:function fun(a, b) {

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

console.log("b = " + b);}

var obj = {

name: “obj”,};

fun.apply(obj, [2, 3]);//a = 2, b = 3

call()和apply()this情况

解析:

  1. 以函数形式调用时,this永远都是window

    2.以方法的形式调用时,this是调用方法的对象

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

    4.使用call和apply调用时,this是call()和apply()里指定的对象

24 立即执行函数

解析:函数定义完,立即被调用,这种函数叫做立即执行函数

  1. 立即执行函数往往只会执行一次

例如:

(function (a, b) {

​ console.log("a = " + a);

​ console.log("b = " + b);

})(123, 456);

类似于-----sum(123,456), sum跟立即执行函数中前一个()都是对象

25 作用域(Scope)

25.1 全局作用域

解析:

  1. 直接编写在script标签中的JS代码,都在全局作用域
  2. 全局作用域在页面打开时创建,在页面关闭时销毁
  3. 在全局作用域中有一个全局对象window,它代表的是一个浏览器的窗口,它由浏览器创建我们可以直接使用
  4. 在全局作用域中,创建的变量都会作为window对象的属性保存
  5. 在全局作用域中,创建的函数都会作为window对象的方法保存
  6. 全局作用域中的变量都是全局变量,在页面的任意的部分都可以访问的到
25.2 函数作用域

解析:

  1. 用函数时创建函数作用域,函数执行完毕以后,函数作用域销毁

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

  3. 在函数作用域中可以访问到全局作用域的变量

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

  4. 当在函数作用域操作一个变量时,它会先在自身作用域中寻找,如果有就直接使用;

​ 如果没有则向上一级作用域中寻找,直到找到全局作用域;

​ 如果全局作用域中依然没有找到,则会报错ReferenceError(引用错误)

  1. 在函数中要访问全局变量可以使用window对象

26 声明提前

26.1 变量的声明提前

解析:

  1. 使用var关键字声明的变量,会在所有的代码执行之前被声明(但是不会赋值)
  2. 如果声明变量时不使用var关键字,则变量不会被声明提前
26.2 函数的声明提前

解析:

  1. 函数声明形式创建的函数 function 函数(){},会在所有的代码执行之前就被创建,所以我们可以在函数声明前来调用函数

例如://函数声明,会被提前创建

function fun() {

console.log(“我是一个fun函数”); }

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

例如: //函数表达式,不会被提前创建

var fun2 = function () {

console.log(“我是fun2函数”);

};

  1. 函数中,不使用var声明的变量都会成为全局变量

function fun5() {

c = 10 // 全局变量

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

}

27 debug(断点)

解析:

  1. 断点可以对每个值的流程进行查看,可以使用火狐、谷歌等浏览器

  2. 控制台找到可以断点模块,添加监视,进行流程查看

28 this参数

解析:解析器在调用函数时每次都会向函数内部传递进一个隐含的参数,这个隐含的参数就是this,this指向的是一个对象,这个对象我们称为函数执行的 上下文对象

根据函数的调用方式的不同,this会指向不同的对象

  1. 以函数的形式调用时,this永远都是window

例如:

function fun() {

console.log(this.name);

}

fun();

  1. 以方法的形式调用时,this就是调用方法的那个对象

例如:

function fun() {

console.log(this.name);

}

//创建一个对象

var obj = {

name: “孙悟空”,

sayName: fun

};

obj.sayName();

29 原型(prototype)

解析:

  1. 我们所创建的每一个函数,解析器都会向函数中添加一个属性prototype
  2. 这个属性对应着一个对象,这个对象就是我们所谓的原型对象
  3. 如果函数作为普通函数调用prototype没有任何作用
  4. 当函数以构造函数的形式调用时,它所创建的对象中都会有一个隐含的属性,指向该构造函数的原型对象,我们可以通过 __ proto __ 来访问该属性
  5. 原型对象就相当于一个公共的区域,所有同一个类的实例都可以访问到这个原型对象,我们可以将对象中共有的内容,统一设置到原型对象中。
  6. 当我们访问对象的一个属性或方法时,它会先在对象自身中寻找,如果有则直接使用;如果没有则会去原型对象中寻找,如果找到则直接使用
  7. 我们创建构造函数时,可以将这些对象共有的属性和方法,统一添加到构造函数的原型对象中。这样不用分别为每一个对象添加,也不会影响到全局作用域,就可以使每个对象都具有这些属性和方法

例如:

function MyClass() { }

//向MyClass的原型中添加属性a

MyClass.prototype.a = 123;

//向MyClass的原型中添加一个方法

MyClass.prototype.sayHello = function () {

alert(“hello”); };

var mc = new MyClass();

console.log(MyClass.prototype);

console.log(mc.__ proto__ == MyClass.prototype); //true

对象属性检查

  1. 使用in检查对象中是否含有某个属性时,如果对象中没有但是原型中有,也会返回true

例如:console.log(“name” in mc);

  1. 可以使用对象的hasOwnProperty()来检查对象自身中是否含有该属性,该方法只有当对象自身中含有属性时,才会返回true

例如:console.log(mc.hasOwnProperty(“age”));

console.log(mc.hasOwnProperty(“hasOwnProperty”)); //false, hasOwnProperty方法不在hasOwnProperty上

console.log(mc.__ proto__ . __ proto__.hasOwnProperty(“hasOwnProperty”)); //true

原型对象也是对象

解析:原型对象也是对象,所以它也有原型

  1. 当我们使用一个对象的属性或方法时,会现在自身中寻找,自身中如果有,则直接使用;如果没有则去原型对象中寻找,如果原型对象中有,则使用
  2. 如果原型中没有则去原型的原型中寻找,直到找到Object对象的原型
  3. Object对象的原型没有原型,如果在Object原型中依然没有找到,则返回undefined

console.log(mc.__ proto__ .__ proto__ .object) //undefined

console.log(mc.__ proto__ .__ proto__ .__ proto__) //null

30 修改原型中的toString

例如:

function Person(name, age, gender) {

this.name = name;

this.age = age;

this.gender = gender }

var per = new Person(“孙悟空”, 18, “男”);

console.log(per);//输出[object Object]

目的:

为了输出是如下形式:Person[name=孙悟空,age=18,gender=男];给对象添加个toString()方法

结果:

per.toString = function(){

return “Person[name=”+this.name+",age="+this.age+",gender="+this.gender+"]"; };

问题:如果是其他对象又要手动改变对象,不好

疑问:toString()方法在哪里的?

查找:console.log(per.__ proto__ . __ proto__.hasOwnProperty(“toString”));//在对象的原型的原型中

方案:修改Person原型的toString

Person.protoType.toString = function () {

return “Person[name=” + this.name + “,age=” + this.age + “,gender=” + this.gender + “]”;}

31 垃圾回收GC(garbage collection)

解析:

  1. 程序运行过程中会产生垃圾,垃圾积攒过多会导致程序运行的速度过慢
  2. 当一个对象没有任何的变量或属性对它进行引用,此时我们将永远无法操作该对象,这种对象就是一个垃圾,这种对象过多会占用大量的内存空间,导致程序运行变慢
  3. JS中拥有自动的垃圾回收机制,会自动将这些垃圾对象从内存中销毁
  4. 需要做的只是要将不再使用的对象设置null即可

例如:

var obj = new Object();

obj = null;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值