Js DOM BOM Jquery Vue笔记课件资料_第1页
Js DOM BOM Jquery Vue笔记课件资料_第2页
Js DOM BOM Jquery Vue笔记课件资料_第3页
Js DOM BOM Jquery Vue笔记课件资料_第4页
Js DOM BOM Jquery Vue笔记课件资料_第5页
已阅读5页,还剩110页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

张东

准备三样东西:

1.书-犀牛书:JavaScript权威指南

2.微信公众号:前端大全

3.上届笔记:

共享资料:不需要外网,且没有限制

用户名:tarenacode

密码:code_2015

规矩:禁止记笔记

第三阶段:

1.JS高级:JS最核心的原理——画图8天

思维导图:

2.D0M:专门操作网页内容的一套对象和函数4天

增删改查事件绑定

思维导图:

3.jQuery:DOM的简化版-PC4天

思维导图:

4.Vue:前端开发的终极简化-5天

思维导图:

按照PPT234三页,安装和配置regexpbuddy软件

正课:

1.正则表达式:

2.字符串的正则函数:

二.字符串的正则函数

1.查找敏感词:4种:

(1).查找一个固定的敏感词在字符串中的位置:

a.vari=str.indexOf("敏感词",fromi)

位置〈-的〈-敏感词

b.在str中从fromi位置开始找下一个"敏感词,'的位置

c.返回值:

1),如果找到敏感词,返回敏感词第一个字在字符串中的下标位置

2).如果没找到敏感词,返回-1

d.如果从头(0位置)开始找,可省略第二个参数fromi。不写fromi,默认就是从0位置

开始。

e.问题:只能查找一个固定的敏感词,只要敏感词内容发生变化,就找不到了!

(2).用正则表达式模糊查找敏感词的位置:

a.vari=str.search(/正贝l]/i)

b.在str中查找第一个符合正则要求的敏感词的位置

c.返回值:同indexOf

1).如果找到,返回敏感词第一个字的位置

2).如果没找到,返回-1

d.问题1:所有正则默认是区分大小写的!

解决:在第2个/后加i表示ignore忽略

e.问题2:只能获得敏感词的位置,无法获得敏感词的内容

(3),查找敏感词的内容:

a.vararr=str.match(/正则/i);

b.在str中查找第一个符合正则要求的敏感词的内容和位置

c.返回值:

1).如果找到,返回一个数组,包含两个元素:

arr:[0:"敏感词内容","index":"位置"]

〃arr["O"]arr["index"K>

I如果是数字如果是字符串

I可省略""

可改为.index

、arr[O]arr.index/

2).如果没找到,返回null

2.替换敏感词

3.切割字符串

作业:

1.编写一个正则表达式,可防住:微信weixinwx同时两个字中间加不加空格应该都能

防住。

2.百度一个自己可以看懂并记住的验证电子邮件格式的正则表达式

第二天

正课:

1.String的正则函数

2.RegExp对象

3.Function

一.String的正则函数:

1.查找敏感词:4种:

(1),查找一个固定的敏感词出现的位置:

vari=str.indexOf("敏感词"[,fromi])

(技术手册中,参数中的口,代表可选)

(2).用正则表达式模糊查找一个敏感词的位置:

vari=str.search(/正贝lj/i);

(3).查找敏感词的内容:2种:

a,只查找一个敏感词的内容和位置:

vararr=str.match(/正贝lj/i)

arr:[0:"敏感词的内容","index":敏感词所在位置]

如果没找到,返回null

问题:一次只能查找一个敏感词

b.查找所有敏感词的内容:

1).只要在第二个/后加g意思是global全部

2).问题:一旦加g,就只能返回敏感词的内容,无法返回位置了!

3).vararr=str.match(/正贝lj/ig)

4),返回值:

i.如果找到敏感词,就返回:

arr:[敏感词1,敏感词2,...]

ii.如果没找到敏感词,返回null

(4),既查找每个关键词的内容,又查找每个关键词的位置

单靠string自己的函数无法完成

要用RegExp对象的exec函数

返回值规律:

如果函数返回的是下标i,则找不到都返回-1

如果函数返回的是数组,则找不到都返回null

强调:如果一个函数有可能返回null,那么这个函数的执行结果,决不能直接使用!必须

先验证不是null,才能用!如果是null,必须提供备选方案!

2.替换敏感词:2种

(1),简单替换:将所有敏感词都替换为统一的新值

a.str=str.replace(/正则/ig,"新值")

b.查找str中所有符合正则要求的敏感词,替换为统一的新值。

c.问题:js语言中字符串是不可变类型!字符串的所有函数,都无权修改原字符串,只

能返回修改后的新字符串,原字符串保持不变!所以,今后只要想获得字符串修改后的新值,

必须自己用标量=接住函数返回的新字符串!

d.问题:如果不加g,replace默认只能替换第一个敏感词。所以,今后,只要找到一组

以上的敏感词,要替换,都要加g,表示必须替换完所有才可以下班!

(2).高级替换:根据每个敏感词的不同,动态选择不同的新值替换!

a.str=str.replace(/正贝!j/ig,function(keyword){

return根据本次获得的不同keyword返回不同的新值

})

b.原理:

1).replace中每遍历到一个keyword,就会自动调用一次回调函数function。--信

任!

2),每次调用函数时,都会自动传入本次找到的敏感词内容给形参keyword信

任!

3),在函数内,由我们自己写的代码对本次拿到的敏感词keyword进行加工,然后

返回要替换的新值!

4).replace会自动将本次函数调用返回的新值替换到本次敏感词的位置上!一一信

任!

回调函数callback:

虽然是自己定义的函数,却不是自己亲自调用,而是交给其他函数去调用!将来,调

用几次,每次调用传入什么值,与咱们无关!

比如:对数组中的数字元素升序排列

arr.sort(function(a,b){returna-b})

难点:看不见何时执行,执行了几次!

学习方法:在回调函数中加入输出语句,让回调函数的执行过程和参数值,都显示出

来!

(3).衍生操作:删除敏感词,其实就是将敏感词替换为空字符串

3.切割字符串:2种:

切割:将一个字符串,按照指定的切割符,切割为多段子字符串。

(1).简单切割:切割符是简单的固定的

a.vararr=str.split("切害府)

b,将字符串str,按其中的"切割符",切割为多段子字符串,保存进数组中返回。

c.强调:切割后,结果中不再包含切割符

(2).复杂切割:切割符是复杂的变化的

a.vararr=str.split(/正则/i)

b,将字符串str,按符合正则表达式要求的"切割符",切割为多段子字符串,保存进数

组中返回。

(3).常用操作:打散字符串为字符数组

a.为什么:有时我们需要对字符串执行数组常用的操作,比如,翻转,排序。。。但是,

字符串家没有这些函数

b.解决:将字符串打散为字符数组,就可以用数组家的函数了。只不过,处理完,记得

再拼回字符串。

c.如何:vararr=str.split("")

二.RegExp对象:

1.什么是:专门保存一条正则表达式,并提供使用正则表达式执行验证和查找操作的函数

的对象

2.何时:只要在程序中使用正则表达式,都要先创建正则表达式对象,再使用。

3.如何:

(1).创建:2种:

a.如果正则表达式是固定不变的:varreg=/正则/ig;

b.如果正则表达式需要根据其他数组等动态生成:

1).问题:〃之间是正则表达式的地盘,不能写js语句。所以,在〃之间无法用程序

动态生成正则表达式。

2).varreg=newRegExp("正贝!T'Jig'')

3),创建一个正则表达式对象,其中保存一条正则表达式

4).newRegExp。创建出的正则表达式和用〃出的完全一样

5).因为newRegExp()要求用字符串形式的正则表达式来创建对象,所以不用加〃

(2).RegExp对象提供的函数:

a.验证字符串的格式:

1).varbool=reg.test(str)

2),意思是:用正则表达式reg,去检查字符串str是否符合正则表达式的要求

3).如果符合要求,就返回ture,否则就返回false!

4),坑:正则表达式,默认只要在str中找到部分匹配的内容,就返回true,不要求

完全匹配

5).解决:今后只要是验证,都要在正则中前加入后加$,表示从头到尾,必须完全

匹配!

b.查找敏感词:既查找每个敏感词的内容,又查找每个敏感词的位置:

1).vararr=reg.exec(str)

2).意思是:在str中查找符合reg要求的下一个敏感词

3),返回值:和match不加g时完全一样

i.如果找到:只返回本次找到的一个敏感词的内容个位置,放在一个数组中:

arr:[0:"敏感词内容",index:"敏感词位置"]

ii.如果没找到,返回null

4).原理:

i.exec每找到一个敏感词,就在数组中0位置放入本次敏感词的内容,在数组index

位置放入本次敏感词的位置。

ii.exec每找到一个敏感词还会修改正则表达式reg对象内部的一个lastindex为当

前位置+敏感词.length。因为lastindex控制着下次开始的位置,所以下次exec执行时,自动

就可以跳过本次找到的敏感词向后找。

iii.每找到一个新的敏感词,就覆盖旧的数组中的敏感词,所以exec一次只能返回

一个当前敏感词的内容和位置。

|/小[\u4e00-\u9fa5]/g,lastlndex=O

下次开始的位置

老师:请用小红我的朋友造句。小亮:小红是我的朋友。

③reg.lastlndex=l6+小亮.length

第三天

正课:Funtion

1.复习函数

2.重载

3.匿名函数

4.作用域和作用域链

5.***闭包

一.复习函数:

1.什么是函数:

(1).用法:保存一段可重用的代码段的程序结构,再起一个名字。

(2).本质:内存中保存一段代码段的对象

2.何时:任何重用的代码,必须封装在一个函数中,再反复使用函数。——DRY(Don'trepeat

yourself)

3.如何:

(1).创建:3种:

a.用声明方式创建:

function函数名(形参列表){

函数体;

return返回值;

}

1).形参:

i.什么是:函数中专门接受外部传入函数内的值的局部变量

ii.何时:如果一个函数内不确定某些数据,需要外部传入才能正常执行时,就要用

形参

iii.为什么:让函数变得更灵活

iv.调用函数时,实参向形参传值,其实等效于赋值!

2),返回值:

i.什么是:函数中的执行结果,返回到函数外部

ii.何时:调用者需要获得函数中的执行结果时,才用返回值

iii.return,其实可以单用!表示退出函数的意思。

breakvsreturn

break只退出循环

return会退出整个函数

3).问题:会被整体声明提前

i.什么是声明提前:

在程序开始执行前

先将var声明的变量和function声明的函数,提前到当前作用域的顶部集中创

赋值留在原地

ii.问题:破坏了程序原有的执行顺序

b.用赋值方式创建函数:

var函数名=function(}

1).使用上,与声明方式创建出的函数用法完全相同

2),好处:不会被声明提前

3),揭示:函数其实也是一个对象

函数名只是一个变量

函数名通过函数对象的地址引用这函数对象

c.用new创建:

var函数名=newFunction("形参1","形参2",.,"函数体")

二.重载(overload):

1.什么是:相同函数名,不同形参列表的多个函数,在调用时,可自动根据传入实参值得不

同,自动匹配对应的函数执行

2.为什么:减少函数名的个数,减轻调用者的负担

比如:数组中:arr.splice(5,l)删除

arr.splice(5,0,100)插入

arr.splice(5,1,100)替换

3.何时:只要一项任务可能根据传入参数的不同,执行不同的逻辑时,就要用重载

4.如何:

(1).问题:js语法默认不支持重载!因为js中不允许多个同名函数同时存在。如果存在,

最后一个函数会覆盖之前所有!只有最后一个函数可以留下来!

(2).解决:js借助arguments对象来变通实现重载效果

a.什么是arguments:每个函数内自带的,自动接收所有传入函数的实参值的类数组对

象。

b.类数组对象:长得像数组的对象

1).相同点:1,下标,2..length,3.用for遍历

2),不同点:类型不同,所以不能使用数组加的函数

c.如何使用:

1),只定义一个函数,且不要给形参变量!

2),在函数内根据arguments的长度或内容,判断执行不同的操作

d.以后要不要定义形参?一定要写形参,只有重载时,才被迫省略形参

1),告诉调用者如何使用该函数

2).形参变量名是见名知意的

3),自己起的形参名都短!

三.匿名函数:

1.什么是匿名函数:创建函数名不起名的函数

2.为什么:节约内存!

3.何时:只要一个函数只使用一次,不会重复使用,都要首选匿名函数

反之,如果一个函数可能被反复使用,就必须起名字

4.如何:

(1).回调函数:

(2),匿名函数自调:

a.什么是匿名函数自调:定义一个函数后,立刻调用自己

b.为什么:避免使用全局变量:因为即使不用,也不会释放!且容易造成全局污染!

c.何时:今后所有js代码都必须包裹在匿名函数自调中

无非是包在一个大的匿名函数中,还是包在多个小的匿名函数中

d.如何:(function(形参列表){...}乂实参值列表);

e.结果:定义后自动调用。调用后,因为函数没有变量引用着,所以用完就释放了!函

数中的内容,跟着就释放了!

f.匿名函数前后,必须都要加分号。

g.其它写法:

(function(形参列表){...}())

+function(形参列表){...}(实参值列表)

Ifunction(形参列表){…}(实参值列表)

因为+和!都是一种运算符,只要是运算符后跟着的表达式,js引擎都会自动执行其

后的内容

四.作用域(scope)和作用域链:

1.什么是作用域:

(1).作用:一个变量的可用范围

(2).本质:作用域其实是一个保存变量的对象

2.为什么:避免不同范围之间的变量互相干扰

3.包括:2级

(1).全局作用域:

a.什么是:所有程序都可访问到的范围

b.全局作用域其实就window对象:所有在全局范围声明的变量和函数都是保存在

window对象中的成员。

c.放在全局作用域中的变量称为全局变量:

1).优:不会被释放,可反复使用!随处可用!

2).缺:可能造成内存泄漏,且会造成全局污染

d.何时:如果希望一个变量跨多个函数公用,且反复使用时,就要用全局变量。

(2).函数作用域:

a.什么是:仅在函数内部可用的范围,称为函数作用域

b.函数作用域是什么对象?

1).函数作用域其实是一个在函数对象外部临时创建的一个对象。

2).函数的生命周期:

i.定义函数时:每个函数就己经保存了自己的"好友列表"一一其中保存着自己可用

的作用域都有哪些

普通函数的好友列表中,都有两个格子。离自己远的格子中保存着全局作用域

windowo而暂时闲置着离自己近的格子。

ii.调用函数时:

js引擎会在函数对象外部为本次调用临时创建一个作用域对象一一函数作用域对

象(ActivedObject),并且将这个对象的地址保存到离函数近的格子里。

js引擎会在函数作用域对象中保存函数内部所有的局部变量和值

当函数执行过程中,使用变量时,会按照先局部再全局的顺序查找变量使用:如果

在局部找到,就用局部的。除非局部没有找到,才去全局找。

iii.当函数调用后,会释放本次调用临时创建的函数作用域对象。导致函数作用域

中的所有局部变量一起释放了!但是函数对象依然存在。可重复使用。

(3).js中没有块级作用域:

什么是块级作用域:其它语言中这些{}

a.if(){…}else{...},for(){},while(){};do{}while(),

也是一级作用域,。内的变量,出了。就不能用。

比如:Java中:

if(bool){

vara=10;

}else{

vara=100;

}

console.log(a)〃报错!

比如:计算从1加到100

for(vari=l,sum=0;i<=100;i++){sum+=i}

console.log(sum);〃报错!

b.js中,以上程序块的{}都不是作用域,{}内的变量,出来依然可用!

if(bool){

vara=10;

}else{

vara=100;

)

console.log(a)〃正常输出a的值

比如:计算从1加到100

vari=l,sum=0;i<=100;i++){sum+=i

console.log(sum);//5050

4.作用域链:函数对象上保存所有可用的作用域对象的scopes集合(好友列表),就是这个函

数的作用域链

(1).作用域链是在定义函数时就已经确定的,和将来在哪里调用无关!

(2).作用域链保存着函数可用的所有变量。只要不在作用域链上的变量,函数无法使用

(3).作用域链控制着变量的使用顺序:先局部,后全局

五.闭包

1.什么是闭包:

(1).用途:既重用一个变量,又保护变量不被污染的一种机制

(2).本质:闭包其实是一个受到保护的隐藏的作用域对象

2.为什么:全局变量和局部变量都有不可兼得的优缺点:

(1).全局变量:优:可重用;缺:极易被污染

(2),局部变量:优:仅函数内可用,不会被污染

缺:无法重用!

3.何时:既重用变量,还要保护变量不被污染的时候,就用闭包

4.如何:

(1).用外层函数包裹要保护的变量和内层函数

(2).外层函数将内层函数返回到外部

(3).使用者需要调用外层函数才能获得返回的内层函数对象,反复使用

5.结果:受保护的变量可以被反复使用,并且不受外部的污染

6.闭包如何形成:内层函数的作用域链引用着外层函数的函数作用域对象,导

致外层函数的作用域对象无法释放,形成闭包!

7.闭包的缺点:闭包的函数比普通函数多占用内存空间

8.如何释放:给引用内层函数的变量赋值为null,导致内层函数对象释放,导致外层函数的

作用域对象一起释放了。

9.鄙视:画简图:找3样东西

(1).受保护的变量是谁?(红包)

(2).外层函数共生了几个内层函数?(妈妈一次生了几个孩子)

(3),外层函数被调用了几次?(妈妈生了几次孩子)

结论:妈妈一次生出的多个孩子,公用同一个红包

妈妈多次生出的孩子,分别使用给自的红包

作业:

1.统计一个字符串中每种字符出现的次数?

出现次数最多的是哪个字?共出现几次?

2.varliang="liang";

liang.money=10;

console.Iog(liang.money);//?

3.复习思维导图:运算符和表达式中所有隐式转换!

4.定义函数add,可以计算任意多个数字的和

functionadd(){...}

console.log(add(l,2,3))〃6

console.log(add(l,2,3,4,5))//15

console.log(add(l,2,3,4))//10

5.作业:看视频,画图,判断输出结果;

vara=10;

functionfun(){

console.log(a)

}

(function(){

a=100;

fun();//100

})();

6.作业:定义一个函数getNum(),每调用一次,返回一个递增的不重复的整数,且不能受外

部干扰

〃假设用n保存序号

getNum()//l

getNum()//2

n=0

getNum()//3

getNum()//4

7.判断输出:

functionfun(){〃妈妈是谁?

〃红包是谁?里边有多少钱?

for(vari=O,arr=[];i<3;i++){

〃函数如果只定义,没调用,就不执行其中的内容!

arr[i]=function(){console.log(i)}

)

returnarr;〃共生了几个孩子

}

varfuns=fun();〃妈妈生了几次

funs[0]();//?

funs[l]();//?

funs[2]();//?

第四天

正课:面向对象

1.什么是面向对象

2.封装

3.继承

一.什么是面向对象:

L什么是对象:

(1).用途:程序中描述现实中一个具体事物的属性和功能的程序结构

(2).本质:内存中一块集中存储多个属性和功能的存储空间,再起一个名字

2,为什么:为了大量数据的管理和维护

3.何时:今后所有程序因为不可能只维护一样东西,都是要维护很多数据,所以都要用面向

对象来开发。

4.如何:面相对象三大特点:封装,继承,多态

二.封装:

1.什么是:将一个事物的属性值和功能集中存储到一个对象中保存。

2,为什么:为了大量数据的管理和维护

3.何时:只要使用面向对象开发,都要先封装对象,再按需使用对象中的成员

4.如何创建对象:3种:

(1).只创建一个对象:

a.如何:var对象名={

属性名:属性值,

方法名:function(){

)

}

b.问题:对象内自己的函数中,想访问对象自己的属性,如果什么前缀也不加,报not

defined错误!找不到!

因为:任何函数默认只能在自己的好友列表中查找变量使用。虽然方法是在对象内

创建,但是对象的{}不是一级作用域,所以对象中方法的好友列表中是不包含对象自己的属

性的。所以,方法内无法直接使用属性名来访问属性。

c.不好的解决:在方法中写死"对象名.属性名"

为什么:紧耦合,一旦对象名改变,而忘记修改内部的对象名,就会出错!必须内外

对象名同时修改,保持一致,才能正确执行。

d.好的解决:this

1).什么是:当函数调用时,自动生成的,指向正在调用函数的.前的对象的关键词

2).为什么:对象自己的方法都无法直接访问自己的属性

3).何时:只要对象自己的方法中要使用自己的成员时,都要用this!

4).原理:this会自动指向正在调用该函数的.前的对象

5).鄙视:this和定义在哪儿毫无关系!只和谁在调用函数有关!只有在函数调用时,

才能确定this!

(2).如果在创建对象时,暂时不知道对象的内容,可以分两步创建对象

a.先创建一个空对象:varobj={};〃newObject。

new和(),只要写任意一个就行。但是不能都省略!

b.再添加新属性:今后,为一个已有对象中添加新属性,都是用强行赋值的方式添加:

obj.属性名=新值

obj.方法名=function(){...}

js中为一个不存在的属性强行赋值,不但不报错,还会自动创建该属性。

揭示了:一切对象底层其实都是关联数组

1),都有下标可以访问每个成员:

ariT'下标名"]=>都可简写为:arr.下标名

arr.下标名会被自动翻译为标准写法:arr「下标名”]

obj["属性名"]=>都可简写为:obj.属性名

obj.属性名会被自动翻译为标准写法:obj["属性名"]

何时使用口,何时使用.?

如果属性名是写死的,首选.

如果属性名是需要动态从变量获得,就必须用口,还不能加""

2),访问一个不存在的下标位置,都不会报错,而是返回undefined

3).都可随时向一个不存在的位置强行赋值,来自动添加该新元素。

4),都可用forin循环遍历,不能用for循环遍历

(3).反复创建多个相同结构的对象:用构造函数:

a.什么是构造函数:专门定义同一类型的所有对象的同一结构的函数

b.何时:反复创建多个相同结构的对象,都要用构造函数

c.为什么:代码重用,重用结构

d.如何:2步:

1),定义构造函数来定义同一类型多个对象的同一成员结构

function类型名(形参列表){

this.属性名=形参;

this.方法名=function(){

…this.属性名…

)

}

类型名通常是一个名词,且首字母大写!

2).调用构造函数反复创建多个同一类型的对象

varobj=new构造函数(实参值列表);

3),结果:在内存中创建了一个包含规定属性结构的对象,且属性值为调用构造函

数时传入的实参值。

4).原理:new的原理:4件事:

i.创建一个新的空对象

ii.自动设置当前子对象继承构造函数的原型对象(自动设置子对象的__proto_一属

性指向构造函数的原型对象)

iii.用新对象调用构造函数,将构造函数中的this统一换成新对象。通过给新对象

强行赋值新属性的方式,为新对象添加规定好的新属性。

iv.返回新对象的地址给变量

5.如何访问对象的成员:

(1).如果访问对象的属性:对象.属性名

(2).如果调用对象中的方法:对象.方法名()

二.继承:

1.什么是:父对象的成员,子对象可以无需创建,就能直接使用!

2.为什么:代码重用!节约内存

构造函数只能代码重用!但是却浪费内存!构造函数会为每个子对象都重复创建多个方法

的副本!

所以,将来构造函数中就不应该有方法定义!应该只包含属性定义就够了。_____________

3.何时:今后,只要发现多个子对象都需要相同的成员时(方法定义或属性值),都要用继承

来实现

4.如何:js中的继承都是通过原型对象来实现的

(1).什么是原型对象:专门集中保存该类型下所有子对象共有成员的父对象。

(2).何时:只要使用继承,就要使用原型对象

(3).如何:

a.创建:不用自己创建,买一赠一:

只要创建一个构造函数,都会附赠一个空的原型对象

functionStudent(){原型对象裕希

this.sname=sname;

this.sage=sage;妈妈

}prototype.constructoi;

b.何时继承:new的第2步让新创建的子对象继承构造函数的原型对象:自动设置新子

对象的__proto_JS性指向构造函数的原型对象

只有从proto属性指出的关系,才叫继承关系!

c.结果:子对象将来,不需要重复创建,就可以使用保存在原型对象中的成员(方法或

属性值)

以上三步都不用自己写!已经在内存中定义好了,咱们直接使用!

d.如何向原型对象中添加新属性:只能强行赋值!一一唯一需要自己做的一步操作

构造函数.prototype.方法名=function(){…}

5.自有属性和共有属性:

(1).自有属性:直接保存在当前子对象中,仅归当前子对象独有的属性。

只要构造函数妈妈肚子里的属性,都会成为孩子的自有属性。妈妈肚子里有什么,

孩子将来自己就有什么!

(2).共有属性:保存在父对象中,归多个子对象共有的属性

(3).获取属性值:都可用"对象.属性名"

(4).修改属性值:自有属性可用子对象自己修改,而共有属性不能用子对象修改,只能

用原型对象修改。

如果强行用子对象修改共有属性,会为这个子对象自动添加一个同名的自有属

性,从此这个子对象和大家在这个属性的使用上分道扬镶。

6.内置对象的原型对象:

(1).ES标准中规定的11种内置对象:

String,Number,Boolean包装类型

ArrayDateMathRegExp

Error

FunctionObject

global(在浏览器中被window代替)

(2).除了Math和global外,其余都是一种类型:

a.每种类型中都有构造函数,专门负责创建这个类型的子对象。所以才能new!比如:

newArray(),newDate(),newRegExpO

b.每种类型中都有原型对象,专门保存这个类型的所有子对象共有的函数!所以,将来

看这个类型都有哪些函数可用,就看这个类型的原型对象。比如:所有数组都可以.sort。,都

可以.push(),是因为数组类型的原型对象中包含这些函数,所以孩子们才能直接使用!

(3),为内置类型如何扩展新函数:

其实就是定义一个函数保存在这个类型的原型对象中

比如:为数组类型添加一个求和的方法sum,让所有数组家孩子都可以对内容求和:

Array.prototype.sum=function(){

vartotal=0;

for(vari=O;i<this.length;i++){

total+=this[i]

}

returntotal;

}

调用时:

[l,2,3].sum()//6

强调:原型对象中的方法中的this,指向将来调用这个方法的点前的某一个具体

子对象。与定义在哪儿无关。

(4).包装类型:

a.什么是包装类型:专门封装一个原始类型的值,并提供对原始类型的值执行操作的函

数的对象

b.为什么:因为原始类型的值只是一个值而已,没有任何自带的功能(函数/属性)。

c.何时:不用自己用,都是自动使用。只要试图对原始类型的值调用函数或访问属性时,

都会自动创建该类型的包装类型对象。我们访问的函数或属性,其实都是包装类型对象提供

的。

比如:"hello''.toUpperCase()

等效于自动newString("hello"),toUpperCase()

d.包装类型对象在调用完函数后,自动释放,不会保留下来。

e.为包装类型添加新的自定义函数:

1),包装类型也包含两部分:构造函数和原型对象

2).只要将新的自定义方法自动添加到包装类型的原型对象中,就可以让所有该类

型的值使用该方法。

创建对象:3种方式:

1.只能创建一个对象,且已知对象的内容

varobj={属性名:属性值,方法名:function(){...}}

2.只创建一个对象,但是暂时不知道对象的内容

varobj={}

obj.属性名二属性值;

obj.方法名=function(){...}

3.反复创建多个相同结构的对象时:

function类型名(属性形参){

this.属性名二形参;

this.方法名=function(){

…this.属性名...

}

}

varobj=new类型名(属性值列表)

总结:继承:只要所有子对象共有的方法或属性值都要强行赋值到构造函数的原型对象

中保存。

构造函数.prototype.方法名=function(){...}

构造函数.prototype.属性名=值

总结:this

1.obj.fun()this->obj

2.fun()this->window

3.newFun()this->new新对象

作业:

1.this的笔试题

第五天

正课:

1.面向对象

2.ES5

一.面向对象

1.继承:

(1),原型链:

a.什么是:多级父对象逐级继承形成的链式结构

b.保存着一个对象可用的所有成员。

1).只要这个对象的原型链中包含的成员,不管是定义在哪一级父对象中,该都可

使用。

2),反之,如果不包含在原型链中的成员,该对象无法使用!

c.控制着成员的使用顺序:先用自有的,如果自己没有,才用共有的成员

2.多态:

(1).什么是多态:一个函数在不同情况下表现出不同的状态

(2).包括2种情况:

a.重载:

b.重写(override):如果子对象觉得从父对象继承来的成员不好用,可在子对象内部定

义和父对象成员同名的自有成员。结果,从此子对象只用自己的自有成员,而不再使用父对

象继承来的同名成员。

1),为什么:不是所有从父对象继承来的成员都是好用的!

2).何时:如果子对象觉得从父对象继承来的成员不好用,就可以重写

3),如何:在子对象内部定义和父对象成员同名的自有成员.

4),结果:从此子对象只用自己的自有成员,而不再使用父对象继承来的同名成员。

3,自定义继承关系:如果觉得当前父对象不好用,可以换掉!

(1).只更换一个对象的父对象:只要修改__pr。to__指向新的父对象就行了

child.__proto__=father

Object.setPrototypeOf(child,father)推荐

修改(原型〈-的〈-child)为father

(2).修改所有子对象的爹:其实就是修改构造函数的prototype属性指向新的原型对象

时机:在创建子对象之前,就要换!

构造函数.prototype=新原型对象

(3).两种类型间的继承:看视频!

总结:面向对象三大特点,也是三个步骤:

1.封装:创建对象3种方式:

(1).varobj={属性名:值,方法名:function。{…}}

(2).varobj={}obj.属性名=值;obj.方法名=function(){…}

(3).function类型名(属性参数列表){

this.属性名=属性参数

)

varobj=new类型名(属性值列表)

2.继承:今后所有的方法都应该定义在原型对象中,所有子对象共有

类型名.prototype.方法名=function(){...}

3.多态:如果从爹继承来的成员不好用,可以自己重写同名成员

4.自定义继承:如果觉得当前的爹不满意可以修改原型对象:

(1).只修改一个对象的原型对象:

Object.setPrototypeOf(child,father)

(2).修改当前类型下所有子对象的原型对象:

构造函数.prototype=新原型对象

二.ES5:ECMAScript标准的第5个版本

1.严格模式:

(1).什么是:比普通js运行机制要求更严格的模式

(2).为什么:js语言本身拥有很多广受诟病的缺陷

(3).何时:今后所有项目都要在严格模式下运行!

(4).如何启用严格模式:只要在当前代码段顶部添加"usestrict";

结果:整段代码都会以严格模式运行

(5).新规定:

a.禁止给未声明的变量赋值:

1).10js:一个未声明的变量,可随时强行赋值,结果自动在全局创建该变量一一

全局污染,也会有歧义

2),严格模式:禁止给未声明的变量强行赋值,报错:xxxisnotdefined。防止全

局污染,也减少了拼写错误导致的误会

b.静默失败升级为错误:

1).什么是静默失败:执行不成功,也不报错一一极其不便于调试程序。

2).严格模式:所有静默失败都升级为错误!都会报错一一便于快速发现问题,调

试程序!

c.普通函数调用中的this不再指向window,而是undefined

1).旧js中:普通函数和匿名函数自调中的中的this,默认指向window。--全局

污染

2).严格模式:普通函数调用中的this不再指向window,而是undefined避免

了全局污染

d.禁用了arguments.callee

1).arguments.callee是专门在当前函数内,引用当前函数自己的关键词

2).何时:只要实现递归调用函数时都用arguments.callee

3),为什么:如果在函数内递归调用自己时,写死函数名,会形成紧耦合。

4).thisvsarguments.callee

i.this指的是正在调用当前函数的.前的对象,而不是当前函数本身。

ii.arguments.callee指的是正在执行的函数本身,而不关心有没有点,或者点前是

谁!

5).禁用arguments.callee不是因为arguments.callee不好,而是因为递归算法不好。

因为重复计算量太大!效率极低!禁用arguments.callee就是在暗示尽量少用递归

6).解决:今后尽量用循环代替递归算法

2.保护对象:

(1).什么是:阻止对对象的属性值以及对象的结构进行不合法的修改。

(2).为什么:js中的对象本身很弱,毫无自保能力

(3).何时:只要希望阻止用户对对象的属性值和结构进行不合法的修改时

(4).如何:

a.保护对象的属性:

1).ES5将对象的属性又进行了细致的分类

i.命名属性:可用.随时访问到的属性一一需要保护

又被细分为2小类:

数据属性:实际存储属性值的属性

访问器属性:不实际存储属性值,只是对另外一个数据属性提供保护!

ii.内部属性:无法用.访问到的,但是对象内实际却存在的属性。比如:class属性。

——不用保护

2).如何保护数据属性:

i.其实每个数据属性,都是一个缩微的小对象

ii.每个数据属性的缩微对象中都包含四个属性:

value:属性值,〃实际存储属性值

writable:true/false,〃控制是否可修改当前属性的值

enumerable:true/false,〃控制是否可被forin遍历到该属性的值半隐藏

configurable:true/false

〃控制是否可删除该属性

〃控制是否可修改前两个开关

)

var更夕—(*•*--**^^/{

/value:1001.\

(eid:1001)/citable:true,。&平控制是否可修改属性值

I热控制是否可被forin遍历到一半隐藏

e总W矍亨,Ienumerable:true:咛因为防得住forin,但是防不住.

)configurable:true,°狂变控制是否可删除该属性

y控制是否可修嫡两钻关

/一旦改为false,不可逆!

iii.开关属性一定不能用.去访问!只能用专门的函数去访问:

Object.defineProperty(对象,"属性名",{

开关名:true/false

})

iv.问题:defineProperty一次只能修改一个属性中的开关,如果修改多个属性中

的开关,要重复写很多遍,很繁琐!

v.解决:

Object.defineProperties(对象,{

属性名:{

开关:true/false,

),

属性名:{…}

})

vi:问题:开关的保护是死板的,不灵活的。无法用自定义规则保护属性

3).访问器属性:

i.什么是:不实际存储属性值,只是对另外一个数据属性提供保护的特殊属性

ii.何时:只要使用自定义规则保护属性时,就必须用访问器属性。

iii.为什么:仅靠开关无法用自定义规则保护属性。

iv.如何:2步:

>首先将要保护的数据属性隐姓埋名,还要半隐藏:

比如:本意是保护年龄属性eage:

Object.defineProperties({

_eage:{

value:属性值,

writable:true,

enumerable:false,

configurable:false

)

})

>然后添加访问器属性来保护这个要保护的数据属性:

Object.defineProperties(对象,{

_eage:{...},

eage:{

get:function(){

returnthis._eage;

},

set:function(value){

if(value>=18&&value<=65){

this._eage=value;

}else{

throwEiroK"年龄超范围!。

)

},

enumerable:true,

configurable:false

}

})

强调:访问器属性eage中,不再有value和writable属性。因为,访问器属

性不实际存储属性值,所以不需要value属性。又因为正是因为writable开关太死板,无

法用自定义属性保护属性,所以才用访问器属性代替的writable开关。所以,也不需要

writable属性了。

V.如何使用访问器属性:访问器属性在用法上和普通属性是完全一样的:

>获取属性值:对象.eage

原理:会自动调用eage中的get(),自动从半隐藏的this._eage属性中获得属

性值返回。

>修改属性值:对象.eage二新值

原理:会自动调用eage中的set(),自动将二后的新值传递给参数value,在set()

中先验证是否符合要求,如果符合要求,才赋值给否则报

valuethis._eageo

错,且不赋值

eric:{试图获取eage:

_eage:26RgetO自动调用eage的get()

eric.eage

eage:

试图修改

set(valeage:

自动调用eage的set()

)>=18

<=65Keric.eage=27

eric.eage=-2

b.保护对象的结构:3个级别:

1).防扩展:阻止对这个对象添加新属性:

i.Object.preventExtensions(obj)

阻止扩展

ii.结果:如果再给obj对象添加新属性,会报错!

iii.原理:每个对象中都隐藏着一个内部属性:extensible:true。所有对象默认都可以

扩展。preventExtensions。自动将内部属性extensible:false,禁止扩展。

2),密封:在兼具防扩展同时,又进一步禁止删除所有属性

i.如何:Object.seal(obj)

ii.原理:1.自动调用preventExtensions。

自动修改所有属性的从此每个属性上不用再加

2.configurable:falseo

configurable:false了。

iii.密封只是禁止添加或删除属性,但是属性值还是可以随意修改的。

iv.大部分对象只要保护到密封级别就够了

3).冻结:兼具密封的基础上,进一步禁止修改所有属性值

i.如何:Object.freeze(obj)

ii.原理:1.自动调用preventExtensions。

2.自动修改所有属性的configurable和writable都为false

iii.何时:多个模块共用的对象内容,不允许随便一个模块擅自修改。

作业:

1.判断一个对象是不是数组类型,共有几种方式?

2.实现两种类型间的继承

第六天

正课:

1.ES5

2.ES6

一.ES5

1.Object.create()

(1).何时:没有构造函数,只有一个父对象,也想创建子对象时

(2).如何:

a.仅创建子对象,继承父对象:

1).varchild=Object.create(father)

2).创建一个新的空对象child,然后自动设置child的_proto___,继承自father。

b.创建子对象,继承父对象同时,为子对象添加自有属性:

1).varchild=Object.create(father;{

属性:{

value:属性值,

writable:true,

enumerable:true,

configurable:false

L

})

坑:因为这些属性是新增的属性,所以所有开关,默认都是false!如果打开,

必须自己显式写出开关:true。_______________________________________________________

2).3件事:

i.创建一个新对象

ii.让新对象继承father

iii.为新对象内添加自有属性

2.call/apply/bind替换this!

何时:只要一个函数中的this不是想要的,都可用这三种方式来替换函数中不想要的this

为想要的对象_____________________________________________________________________

(1).在一次调用函数时,临时替换一次函数中的this为指定的对象

a.函数.call(替换this的对象,实参值列表…)

1),调用一次函数

2).临时替换函数中的this为指定对象

3).将实参值列表直接传给函数的每个形参变量

b.如果传入的实参值列表是放在一个数组中传入的

1).函数.apply(替换this的对象包含实参值的数组)

2).3件事:

i.调用一次函数

ii.临时替换函数中的this为指定对象

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论