day01
am:
前端三大基础知识:
html:专门编写网页内容
css:专门设计网页样式
JavaScript:专门设计网页交互的语言
交互:输入数据,程序处理数据,返回结果
什么是JavaScript:
1、专门设计网页交互的语言
2、运行在JavaScript解释器中
3、“解释”执行——像读书一样
4、互联网第一大语言:JSer
布兰登艾奇:4门语言拼凑出——JavaScript
ECMAScript标准:JavaScript核心语法
微软:JScript
ECMAScript标准:一纸空文
JavaScript和JScript都号称完全实现了ECMAScript标准
W3C:DOM标准:专门操作HTML元素,CSS样式,事件的统一标准!
立即学习“Java免费学习笔记(深入)”;
BOM:专门操作浏览器窗口的工具。
没标准,由浏览器厂商自行实现
JavaScript=ECMAScript+DOM+BOM
Mozilla基金会——>Firefox
JSer最大挑战:浏览器兼容性问题
JavaScript典型用途:
1、客户端数据计算
2、客户端表单验证
3、动画
JavaScript特点:纯文本;解释执行;弱类型;基于对象
如何让使用:
1、使用浏览器自带的js解释器:
F12——>控制台
光标处写脚本代码,回车执行。
console:指代控制台:专门调式程序输出结果的窗口。
log:控制台console提供的一个功能:向控制台输出一行日志。
多行:shift+enter——>换行
**JavaScript中区分大小写!**
**字符串单双引号都行**
2、单独安装专门的解释器软件:node.js Chrome V8
win+R——>cmd——>node
退出:两次Ctrl+c
执行.js文件:1、先cd到.js文件所在路径
2、node 文件名 回车
3、随网页一同运行:
浏览器 包含两种工具:
排版引擎:专门加载HTML内容和CSS样式
解释引擎:专门运行js脚本
<script>元素:专门包含js脚本块的元素<br/><script>中脚本块何时运行?随网页加载,解释执行<br/><script>中都要使用js语法!<br/>html元素的事件“属性”中:<br/>什么是事件?元素可以根据鼠标或键盘的不同操作相应不同的交互行为。<br/>charset必须和文件的存储编码一致<br/><script>解释执行,读到执行。先读先执行。——<script>放置的先后顺序影响程序结 <br/>果。<br/>优化:放在body的最后</script>
一次定义处处使用,一次修改处处生效!
解决:凡是重复编写的代码块,都要封装为一个方法
方法:执行一个专门功能的一组代码的序列。
一般定义在
下的<script>中<br/>语法:function 方法名(){重用的代码块}<br/>*不调不执行*<p>调试:bug? debug:解决问题,排除错误<br/>只要没反应或效果没出来就是出错!——>F12<br/>查看错误原因——>定位错误位置!<br/><script>脚本块中的错误,仅影响“当前脚本块”中出错“位置之后”的脚本执行。<br/>不影响<script>之外的其他元素加载或脚本执行。<br/>function中的错误:只有调用方法是才触发!<p>页面内部脚本块问题:仅当前页面可用!<br/>解决:外部.js文件!<br/>什么是.js文件:专门保存js脚本源代码的文件。<br/>源代码都要放到js解释器才能执行。<br/>如何使用.js文件?2步:1、创建.js文件,编写源代码 2、在页面引入外部.js文件<br/>内外部同名方法,解释执行!<p>pm:<br/>JavaScript=ECMAScript(核心语法)+DOM(操作网页内容)+BOM(操作浏览器 <br/>窗口)<p>ECMAScript(核心语法)<br/>*区分大小写*<br/>*字符串必须用引号(单双都行)包裹*<br/>*每条语句结尾都建议有分号*<p>语句:让程序可以做一件事的一行命令<br/>脚本块:多行语句的序列<br/>程序:让计算机可以模拟执行人类的想法!<br/>注释:不会被解释执行或显示的代码说明——给程序员看的<br/>注释也占网页流量!生产环境必须去掉!<br/>HTML注释:<!----><br/>CSS注释:/**/<br/>JS注释://单行注释 /*多行注释*/<p>*变量*<br/>什么是变量?内存中专门存储数据的空间<br/>程序都是在内存中运行<br/>任何程序:IPO:Input Process Output<br/>数据 数据 数据<br/>何时使用变量?只要在程序中临时存储数据,都要放在变量中<br/>怎么使用变量?声明,命名,初始化和使用<br/>声明:在内存中开辟一个存储空间,并且起一个名字<br/>怎么声明?var 变量名;<br/>赋值:将等号右边的数据,装入等号左边的变量中!<br/>如果未赋值:js默认赋值为undefined<p>命名规则:见名知意<br/>保留字、关键字不能当变量名<br/>保留字:js中已经占用的特殊意义的关键字<br/>使用:使用变量名等于直接使用变量中存储的数据<br/>+:拼接多段文字为一句话!<p>常量:一旦创建,值不可改变的特殊变量<br/>如何使用常量:const 常量名=常量值;<p>强调:只有等号可以向变量中存入新值。普通运算不会改变变量的值。只是使用变量的 <br/>值。<br/>只要带var就是声明,只要声明就会开辟内存空间、<br/>js中新同名变量的空间会替换旧的空间。<br/>有几个var,就会创建几个存储空间。<p>数据类型:变量中存储的数据类型。<br/>js是弱类型:变量本身没有类型。只有变量中的值才有类型。<br/>一个变量,可以反复保存不同类型的数据。<br/>为什么要有数据类型:现实中所有数据根据用途不同,都分为不同数据类型。<p>原始类型:数据保存在变量本地!<br/>number类型:表示一切用于比较或数学计算的数字<br/>程序中数字分整数、浮点数(现实中的小数)<br/>js中一切数字都用number保存,不分整数类型和小数类型<br/>如何定义number类型?不带引号的数字字面量<br/>程序中数字类型的舍入误差:程序中不能准确表示1/10,就好像现实中不能准确表示 <br/>1/3一样!<br/>如何修正:按指定位数四舍五入:数字.toFixed(小数位数)<br/>今后计算结果小数位数超长,说明碰到舍入误差。按位四舍五入。<br/>精度计算不要用JavaScript<p>string类型:一串字符的序列!<br/>Unicode:对所有语言文字中的字符编号<br/>Why“因为计算机只处理数字,无法处理文字。<br/>计算机处理unicode编号,就等效于处理编号对应的文字。<br/>转义字符:专门表示非打印字符以及特殊符号<br/>如何使用转义字符:特殊符号 比如:
换行 、 tab键<br/>如果字符串中包含与语法相冲突的特殊字符,要用转为原文<p>*字符串变量的内容一旦创建补课费改变!如果改变,只能创建新字符串,抛弃旧字符串 <br/>。*<br/>鄙视题!<br/>var str = "Hello";<br/>str = str + “Word”;<br/>3个!<p>boolean类型:仅有两个值的特殊数据类型:true,false<br/>何时使用boolean?只要一个值只有真假两种情况,就用boolean类型<p>undefined类型:表示一个变量仅声明过,但从未赋值。所有未赋值的变量,默认值都 <br/>是undefined。<br/>undefined类型的值还是undefined!<p>原始类型的大小:<br/>number:整数4字节,浮点8字节<br/>string:每个字符两字节<p><br/>day02<br/>回顾:<br/>JavaScript:ECMAScript(核心语法)<br/>DOM(操作网页内容)<br/>BOM(操作浏览器窗口)<br/>ECMAScript:标准<br/>Netscapt:javaScript Microsoft:JScript<p>变量:内存中存储数据的一块空间<br/>一切数据必须存在变量中<br/>声明:var 变量名——>在内存中开辟一块空间<br/>赋值:变量名=值——>将值保存到左边的变量空间中备用<br/>使用:使用变量名,就等效于直接使用变量中的数据<p>数据类型:<br/>why:存储空间的大小,用途<br/>原始类型:数据保存在变量本地<br/>number string boolean undefined null<p>string:字符串内容一旦创建不能改变<br/>var str = "Hello";<br/>str = str + "World";<br/>3个!<p>正课:<br/>数据类型间的转换:<br/>隐式转换:程序自动转换数据类型(坑)<br/>弱类型:1、变量声明是不必限定数据类型,今后可能保存任何数据类型<br/>2、数据类型间可以自动类型转换<br/>仅考虑+:只要有字符串参与,一切类型都加""变为字符串<br/>如果没有字符串,都转换为数字计算:其中true——>1 false——>0<p>强制转换:程序员通过调用专门函数,手动转换类型<br/>2 string:x.toString();——>将x转为字符串类型<br/>2 number:Number(x);——>将任意类型转为number类型<br/>string——>number:<br/>转为整数:var num = parseInt("str");<br/>读取字符串中的整数部分<br/>1、从第一个字符向后读。<br/>2、如果碰到第一个数字字符,开始获取数字,再次碰到不是数字的字符,停 <br/>止读取<br/>3、如果开头碰到空格,忽略<br/>4、如果碰到的第一个非空格字符,不是数字,说明不能转——>NaN: Not <br/>a Number<br/>什么是NaN:不是数字(内容)的数字(类型)<br/>转为浮点数:var num = parseFloat("str");<br/>用法和parseInt全完相同<br/>唯一差别:parseFloat认识小数点<p>prompt("提示信息"):专门用于请求用户输入数据,收集数据的对话框!<br/>var str = prompt("提示信息");<br/>*凡是从页面上获得的数据,都是字符串!必须先转换再计算*<p>什么是运算符:程序模拟人类运算的特殊符号<br/>算数运算:-任意类型做-,都会被转为数据类型<br/>如果有参数,不能自动转换为数字,则返回NaN<br/>如果除数为0:Infinity——>无穷大<br/>typeof(x):判断任意数据的类型<br/>被除数%除数——模运算:被除数/除数,取除不尽的余数<br/>何时用:限制一个数不能超过某个最大范围时<p>递增/递减运算:i++ ==> i = i +1;<br/>i++单独用:++放前放后,效果一样:i++ ==> ++i;<br/>i++出现在表达式内部:<br/>前++,前+1,再参与表达式<br/>后++,先用旧值参与表达式。表达式之后再+1<p>关系运算:判断大小!条件判断中使用<br/>结果:成立:true,不成立:false<br/>*自带隐式类型转换*<br/>字符串参与运算:从第一个字符开始,取出每个字符 PK unicode编号<br/>"Hello" H e(101)<br/>"Hi" H i(105)<br/>关系运算中:任何类型和数字比较,都转为数字,再比较<br/>布尔类型参与关系运算,始终转为数字比较<p>PM:<br/>关系运算:现将参与判断的数据,强转为相同类型,再比较<br/>字符串比较:<br/>undefined做==比较:<br/>undefined类型,从null类型继承来的<br/>undefined值被自动转换为null!<br/>undefined == null ——>true<br/>===严格相等:不带自动类型转换的相等比较!<br/>类型和值必须都相等!才返回true。<br/>严格相等最初就是为undefined和null设计的<br/>只要不确定比较的类型,又不希望自动类型转换时,就用===<p>NaN做==:<br/>isNaN(x):专门用来判断一个数据是不是NaN<br/>如果是NaN返回true;如果不是NaN返回false<br/>是<br/>只要不能转换为数字的,都返回true<br/>只要能自动转换为数字的,都返回false<br/>关系运算中"",可以自动转换为false或0<br/>总结:1、普通数据,先转换为相同类型,再比较<br/>2、undefined,就用===<br/>3、NaN,就用isNaN(x)<p>逻辑运算:基于多组关系运算,得出一个结论<br/>&&:而且<br/>||:或者<br/>!:非,颠倒true和false,今后只要颠倒判断结果,就用!<p>短路逻辑:只要前一个判断足以得出最终结论,则后续条件不执行!<p>验证是不是汉字:>="u4E00" && <="u9FA5"<br/>闰年的判断公式:(year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)<p>位移:n << m ——>n*(2的m次方)<br/>n >> m ——>n/(2的m次方)<p>赋值运算:赋值运算结果就是等号右边表达式的结果<br/>扩展的赋值表达式:对已有的数据计算的同时,将结果再存回变量<br/>何时使用:修改原变量值<p>三目运算:根据不同条件,动态返回不同结果!<br/>三目:至少需要3个表达式。<br/>语法:<br/>一个条件,二选一:条件?当条件满足时返回的值:当条件不满足时返回的值<br/>多个条件,多选一:<br/>条件1?条件1满足时的值:<br/>条件2?条件2满足时的值:<br/>条件n?条件n满足时的值:<br/>默认值;<br/>需求1:2个数中取最大的<br/>var score1 = 100;<br/>var score2 = 80;<br/>var result = score1 > score2 ? score1 : score2;<br/>注意:后一个条件中不用包含否定前一个条件的关系判断。<br/>因为,进入后一个条件隐含的条件就是前一个条件不满足。<p><br/>day03<br/>NaN == NaN? false NaN和任何数据比较,永远返回false<br/>今后只要可能判断NaN时,用isNaN(x)<br/>var str = "Hello";<br/>str > 10? str > 10000? false<br/>NaN NaN<br/>关系运算中,字符串比数字,字符串转为数字!<p>注意:逻辑运算中,不要急于将第一个条件之后的++/--提取出来<p>使用变量错误的情况:*没声明的变量,只要使用就出错!*<br/>var name;<br/>console.log(Name);//程序运行错误错误!会导致程序停止<br/>console.log(name);//undefined1<p>函数(方法):封装执行一项专门任务的步骤的代码序列<br/>何时定义方法?只要发现一段代码重复使用,就封装为方法<br/>语法:声明<br/>function 方法名(参数列表){<br/>方法体:步骤清单<br/>return 返回值;<br/>}<br/>调用:方法名(参数值列表);<br/>参数:方法内独有的变量。接收传入数据,在方法内处理。参数让方法变灵活!<br/>如何声明方法参数:不用var!<br/>参数何时被创建?只有方法被调用时才自动创建<br/>返回值:方法执行完成后,由方法返回的数据<br/>定义返回值:不用再声明变量,直接用return值!<br/>为什么定义返回值:因为调用方法的人需要明确的返回结果。<br/>返回值主要给调用者使用。<br/>return:本意退出方法!<br/>退出同时,可返回数据!<br/>可以再任何需要的地方,调用方法执行返回值;<br/>带返回值的方法,使用时,等效于直接使用返回值数据。<p>作用域:一个变量的可用范围!<br/>全局作用域:直接放在全局作用域中的变量,叫全局变量<br/>只要希望所有作用域公用的变量都要声明在全局作用域<br/>window<br/>局部(函数)作用域:声明在方法内部的变量或方法参数的变量都叫局部变量<br/>值传递:将一个变量的值赋值给另一个变量,其实将原变量中的值,复制一份给新变量 <br/>。<br/>js中一切赋值都是值传递!<p>对未声明的变量赋值:js会自动在全局创建该变量!<p>函数作用域和变量作用域完全一样<br/>函数作用域在调用方法时创建,方法执行完立刻销毁!<p>PM<br/>问题:<br/>方法参数:依据方法内部的处理逻辑至少需要几个数据才能正常执行。<br/>方法参数和外部定义了了那些变量没有任何关系。<br/>方法参数作用:1、接收外部传入数据,在方法内处理<br/>2、规定调用方法的人必须提供哪些参数!<p>方法的返回值:根据方法调用者的需要! 如果方法调用者需要明确返回一个结果,就定 <br/>义返回值!否则,可以不定义返回值!<br/>何时必须使用变量接住?方法的返回值,后续程序可能反复使用!<p>鄙视题:<br/>var num = 0;<br/>function f1(num){<br/>var num = 100;<br/>console.log(num);<br/>}<br/>f1();<br/>console.log(num);<br/>//100 0<p>正课:<br/>自定义函数:<br/>全局函数:ECMAScript定义了标准,由个浏览器厂商已经实现的函数。我们直接调用 <br/>!<br/>isNaN(x) parseInt/Float(x)<p>encodeURI( kword ):将url中的非法字符转为单字节符号——编码<br/>decodeURI( kword ):将encodeURI转后的字符串,转换为原文——解码<br/>unicode编码:每个字符2字节<br/>utf-8:字母、数字单字节,汉字3字节<p>url规定参数值中,再次出现保留字,就是非法:<br/>保留字:/ ? $ : 等<p>encodeURIComponent( kword );既能对多字节非法字符编码,又能对单字节非法字符 <br/>编码——今后只使用component就够了<br/>何时使用?将数据通过url发送时,都要先编码再发送<br/>decodeURIComponent( kword );对encodeURIComponent()编码的字符串解码。收 <br/>到编码后的字符串后,都要先解码,再处理。<p>eval():专门执行字符串格式代码<p>程序结构:3种:顺序;分支;循环<p>程序:IPO<br/>需求:找名词——>程序中的数据<br/>两类:输入数据<br/>输出数据<br/>分析处理流程:<p>分支结构:程序运行过程中,可以根据不同的条件,执行不同的任务。<br/>分支结构:if...结构:1件事,要么做,要么不做 <br/>if...else...结构:2件事,二选一执行<br/>else if结构:多件事,多选一执行<p><br/><br/>day04<br/>回顾:<br/>方法参数:方法内处理逻辑必须的数据<br/>参数仅限方法内部使用!方法外无法访问方法的参数变量<br/>参数名称自定义!<br/>返回值:调用者是否需要获得方法的执行结果<br/><br/>分支:if结构 1件事 可做可不做<br/>if...else... 2件事 必须二选一<br/>if...else if...[else...] 多件事 多选一执行<p>正课:<br/>switch...case...多条分支,根据条件判断,选择执行<br/>switch...case...用的是严格相等,不带自动类型转换<br/>语法:swith(表达式){<br/>case 表达式1://如果表达式的值===表达式1的值<br/>代码段1;<br/>case 表达式n:<br/>代码段n;<br/>default://如果表达式的值和都有的case都不相等<br/>默认代码段;<br/>}<br/>运行机制:如果找到与表达式匹配的case,不但执行当前case下的代码,而且之后所有 <br/>代码都被触发!<br/>switch(true){<br/>case socre >= 90: console.log("A");<br/>case score >= 80: console.log("B");<br/>case score >= 60: console.log("C");<br/>default: console.log("D");<br/>}<br/>break:退出当前结构; <br/>多条件公用同一套执行逻辑是,不加break。<br/>switch(true){<br/>case socre >= 90: console.log("A");break;<br/>case score >= 80: console.log("B");break;<br/>case score >= 60: console.log("C");break;<br/>default: console.log("D");<br/>}<p>循环结构:程序反复执行同一套代码段。遇到结束条件,会结束执行。<br/>没有循环结束条件,永远循环呢执行——死循环<p>循环三要输:<br/>1、循环条件:循环继续执行的条件。一旦循环条件不满足,循环立刻退出!<br/>2、循环变量:用于循环条件中做判断的变量。循环变量都会向着循环退出的趋势变化 <br/>(不满足循环条件的趋势)——循环计数器<br/>3、循环体:每次循环要做的事情<p>while循环:当满足条件时,就继续循环做...事<br/>语法:<br/>var 循环变量;<br/>while(循环条件){<br/>循环体;<br/>迭代变化循环变量;<br/>}<br/>break:退出当前结构<br/>while中何时用break:循环条件不满足之前,希望强行退出循环。<br/>如何使用break?可以放在任何需要退出循环的位置。<p>随机数:Math.random();0<=n<1<br/>任意min——max之间取随机数<br/>公式:parseInt(Math.random()*(max-min-1)+min)<p>do-while循环:先执行一次循环体,再判断是否继续!<br/>如果循环条件不满足,循环体至少可以执行一次!<br/>var 循环变量;<br/>do{<br/>循环体;<br/>迭代变化循环变量;<br/>}while(循环条件);<p>*变量声明提前*:“相同作用域内”,var...不论出现在什么位置,解析时,优先提取到 <br/>js开始位置“声明”!<p>for:完全等效于while循环。<br/>循环变量变化规律固定,循环次数已知、固定<br/>for(声明并初始化循环变量;循环条件;迭代变化循环变量){<br/>循环体<br/>}<p>continue:跳过本轮循环,继续执行下一轮循环<p>遇到复杂问题:<br/>先用简单办法做最简单的事情。<br/>从简单办法中找规律!<p> <p>day05<br/>程序 = 数据结构 + 算法<br/>良好的数据结构,可以极大提高程序的执行效率!<p>数组:存储:连续存储多个数据的存储空间<br/>使用:相当于多个变量的集合<br/>why?现实中数据都是批量分类管理<br/>何时使用:只要批量管理多个数据,就要用数组保存<br/>如何使用:创建,初始化,访问数组中的数据<br/>创建:数组都是用[]创建出来的。<br/>var arr = [];——>创建了一个数组对象,数组中包含0个元素<br/>var arr = [90, 34, 23];——>创建了一个数组对象,数组中连续存储3个元素<br/>2个不限制:1、不限制元素的个数! 2、不限制元素数据类型<p>*数组是引用类型的对象*<br/>原始类型:数据保存在变量本地<br/>引用类型:数据不保存在变量本地!保存在“堆”中。<br/>由地址指向实际数据<br/>引用类型特点:可以保存多个数据,而且数据个数随时变化<br/>why?原始类型中只能保存1个值<br/>1个值无法精确描述一个东西<br/>现实中,都是用多个属性共同描述一样东西<br/>对象:凡是存储在堆中的,都是对象!<br/>使用引用类型的对象:使用变量,等效使用对象的地址<br/>使用对象地址,等效于使用对象本身<br/>数组对象支持直接输出数组内容<p>其他数组创建语法:var arr = new Array(num);<br/>new:要在堆中开辟空间!<br/>Array:ECMAScript标准的内置类型<br/>new Array:在堆中创建一个数组类型的存储区域<br/>(num):初始创建num个元素<br/>var arr = new Array(7);<br/>//[undefined, undefined, undefined, undefined, undefined, undefined, undefined]<br/>undefined输出时,变为一个空字符<br/>var arr = new Array(元素1, 元素2,..., 元素n);<p>null:一个变量没有指向任何对象<br/>何时使用null:主动释放对象!主动释放的对象不能被找回<br/>null vs undefined:<br/>null专用于主动释放对象!<br/>undefined:专用于自动初始化任何未赋值的变量<p>垃圾回收:js引擎自动销毁不再被引用的对象!<br/>垃圾回收程序:随js程序运行而后台同时运行<br/>只要对象还有变量引用,就不回收。<p>访问数组:数组一组变量的集合。<br/>如何获得其中一个变量/数据:下标,数组中唯一标识一个元素的序号。从0开始。最后 <br/>一个元素的下标是“元素个数-1”<p>js内置对象不但封装存储,而且封装常用API<br/>API:已经实现的方法!可以直接调用!<br/>Array API:<br/>1、arr.length属性:数组中元素的个数<br/>访问任意数组的最后一个元素:arr[arr.length - 1]<br/>length属性值,随数组长度变化而自动变化!<br/>js中数组可根据程序需要,“自动扩容”,保证程序正常执行<p>数组扩容和缩容:都是设置length属性的值<br/>如果length属性值>旧值,会扩容;反之,缩容(截断)<br/>被截断的元素,不能被找到,不会被回收。只能随数组对象一起回收。<br/>固定用法:在任意数组结尾追加一个新元素:arr[arr.length] = 新值;<p>下午:<br/>栈中的变量 生命周期:和堆完全不同<br/>var a = 5;//全局变量随网页生命周期<br/>function fun(){<br/>var b = 10;<br/>}<br/>fun();//作用域环境栈<br/>/*fun的作用域环境栈 出栈 fun中局部变量,一同消失*/<br/>console.log(b);//refError<br/>结论:局部变量的声明周期和所在方法的作用域环境栈有关<br/>作用域创建,局部变量一同创建<br/>作用域结束,局部变量一同消失<p>什么是数组遍历:对数组中每个元素执行相同的操作<br/>for(var i = 0; i < arr.length; i++){<br/>arr[i]——>当前元素<br/>}<p>关联数组:数组下标可以自定义名称!Key/value对<br/>何时使用关联数组:数组元素的内容无法描述自己的意义时,使用关联数组为每个元素 <br/>起名<br/>关联数组的length属性作废了!<br/>for in:专门遍历关联数组用的!<br/>for(var key in arr){<br/>//从第一个元素开始,将元素的key赋值给临时变量key<br/>arr[key]——>当前正在遍历的元素的值(value)<br/>}<br/>关联数组直接量定义方式:强调:大括号<br/>{"key1":"value1", "key2":"value2", ...}<p>冒泡排序:[3, 5, 3,。。]:见array.html<p>数组常用方法:<br/>x.toString()方法:任何对象都有toString方法<br/>默认用,分割每个元素<br/>将任何对象转为字符串<br/>一般不主动调用,js在需要时自动调用<br/>x.valueOf()方法:同toStrin()<p>var str = arr.join("分隔符"):将数组转为字符串。但是可自定义分隔符!<br/>用法,将字符拼接为单词或句子 chars.join("");<p>var newArr = arr.concat(1个元素值, [数组], ...):将参数拆散成单个元素,追加到数组 <br/>中。<br/>*不会修改原数组,只能返回新数组对象*<p>var subArr = arr.slice(start, end + 1);截取数组下标从start开始,到end位置的元素, <br/>生成子数组对象。*含头不含尾*<p>arr.splice:删除!插入!替换!<br/>删除元素:arr.splice(start, count);<br/>替换元素:arr.splice(start, count, 值1, 值2, ...);<br/>插入元素:arr.splice(start, 0, 值1, 值2, ...)<br/>返回每次删除元素组成的新数组<p>arr.reverse();颠倒所有数组元素<br/>arr.sort();默认升序排序。默认都转为字符串排序!<p> <p>day06<br/>手册:JavaScript——>js对象——>js数组——>Array对象参考手册<br/>回顾:<br/>转为字符串:x.toString()——>任何对象都有toString方法<br/>var str = arr.join("分隔符")——>自定义元素分隔符<br/>固定用法:arr.join("");——>将数组中的字符串无缝拼接为单词或字符串<p>拼接和截取:var newArr = arr.concat(otherArr, 值1, ...)<br/>var subArr = arr.slice(start, end + 1);<br/>复制原始数组中的部分元素,原数组不变<br/>含头不含尾<p>splice:*直接修改原数组!*返回被删除 的元素<br/>删除:[var removed =] arr.splice(start, count);<br/>替换:[var rrmoved =] arr.splice(start, count, 值1, 值2, ...);<br/>自动调整数组容量,容纳所有修改的新值<br/>插入:[var rrmoved =] arr.splice(start, 0, 值1, 值2, ...);<p>正课:<br/>排序:arr.sort();默认按字符串升序排列<br/>自定义排序:2步:Step1:定义比较器函数!<br/>什么是比较器函数?定义任意两值比较策略的方法<br/>比如:num1 - num2 > 0 ——> num1 > num2<br/>num1 - num2 < 0 ——> num1 < num2<br/>function compare(a, b){<br/>return a - b;<br/>}//如果返回>0数,a > b; 如果返回<0数,a < b; 如果返回=0数,a = b;<p>Step2:将比较器函数传递给sort方法!<br/>***如何将方法做参数传递?***<br/>js中方法也是一个对象!方法名就是指向对象的变量名!<br/>function compare(a, b){return a - b;}<br/>//可以定义在使用前后的任何位置<br/>//原因:var声明和function声明自动提前!<br/>相当于:var compare = new Function("a", "b", "return a - b;");<br/>//必须定义在使用之前!原因:仅声明提前,赋值不能提前!<br/>arr.sort(compare);注意!将方法作为对象传递是,仅使用方法名,后不加圆 <br/>括号。<p>降序:颠倒比较结果,可以导致升序变降序<br/>升序:function compareASC(a, b){return a - b;}<br/>颠倒(*-1):function compareDESC(a, b){return b -a;}<p>栈和队列:<br/>什么是栈?后进先出!(LIFO)栈其实就是数组,只不过用一对方法模拟了栈的操作!<br/>栈:只能从数组一端出栈,入栈。另外一端封闭!<br/>操作栈:<br/>结尾入栈出栈:元素下标始终不变,最后一个元素始终最新<br/>入栈:arr.push(值1, ...); <br/>出栈:var last = arr.pop();<br/>开头入栈出栈:所有元素下标随入栈出栈操作而变化<br/>入栈:arr.unshift(值1, ...);<br/>出栈:var first = arr.shift();<br/>队列:FIFFO<br/>入队列:arr.push(值1, ...);<br/>出队列:var first = arr.shift();<p>二位数组:数组的元素又是另一个数组对象!<br/>创建二位数组:创建普通数组,完全一样!<br/>只不过将普通元素,换为一个数组对象而已<br/>var arr = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];<br/>arr[3] = [10, 11, 12];<br/>如何访问二位数组中的任意元素:arr[父数组中的下标][子数组中的下标]<br/>何时使用二位数组:数据包含明显上下级关系<p>内置对象<br/>什么是内置对象?内置对象就是ECMAScript标准中已经定义好的,由浏览器厂商已经 <br/>实现的标准对象!<br/>内置对象中封装了专门的数据和操作数据常用的API。<br/>JavaScript中内置对象:<br/>String,Boolean,Number,Array,Date,Math,Error,Function,Object,Global<br/><br/>包装类型<br/>什么是包装类型?专门封装原始类型的数据,并提供对数据常用操作的内置类型。<br/>为什么要用包装类型?让原始类型的数据也可以像引用类型一样,拥有方法和属性。<br/>JavaScript中的包装类型有三个:<br/>String类型,Number类型,Boolean类型<br/>何时使用包装类型?只要用原始类型的数据调用方法或访问属性,js引擎都会自动创建 <br/>对应的包装类型对象。<br/>方法调用完,包装类型对象自动释放。<br/>var str = "Hello";<br/>//var strObject = new String(str);<br/>str += "world";<br/>//strObject = null;<p>String包装类型:*字符串内容,一旦创建,不可改变*<br/>创建原始类型字符串变量:<br/>直接量:var stuName = "Smith";<br/>类型转换:var priceString = String(190.3);<br/>创建引用类型字符串对象:<br/>var carType = new String("BMW528Li");<p>str.length:返回str字符串中的字符个数<br/>大小写转换:都转小写:str = str.toLowerCase();<br/>都转大写:str = str.toUpperCase();<br/>何时使用:希望大小写一视同仁时,就要先转换,在处理<p> <p>day07<br/>内置对象:见PPT<br/>包装类型:见PPT<br/>var num = 5.678;//原始类型<br/>//num = new Number(num);//包装类型<br/>console.log(num.toFixed(2));<br/>//num = null;//释放包装类型对象!<p>创建字符串:原始类型还是包装类型?是否new<br/>var str = "...";//原始类型<br/>var str = String("...");//原始类型,类型转换<br/>**********************************************<br/>var strObj = new String("...");//包装类型对象<p>转义字符:代替字符串中的非打印字符:
<br/>如果字符串内容中包含和语法冲突的特殊字符,可用转为普通字符<br/>比如:console.log(" js是互联网"第一大语言"");<p>字符串内容一旦创建不能改变!<br/>如果修改,都要创建新字符串,保存新结果,替换旧字符串<br/>var str = "Hello";<br/>var strObj = new String(str);<br/>str = str.toUpperCase();<br/>//strObj = null;<br/>console.log(str);<br/>*规律:所有字符串API,都需要变量接收返回值!*<p>字符串的字符个数:str.length属性<br/>*字符串类型底层其实都是用字符数组实现的*<br/>比如:str[i]<p>大小写转换:大小写字母一视同仁时,先转化,再处理<br/>比如:重名验证,重复邮箱,验证码<p>获取指定位置的字符:var char = str.charAt(index);<p>获取指定位置字符的unicode编码:var num = str.charCodeAt(index);<p>优化:*频繁对字符串+=,要用数组代替!不会产生中间对象*<br/>Step1:每个字符串放入数组<br/>Step2:join("")拼接字符元素<p>今天后要把任何类型变为String,不要用toString,而用+"",效率更高。<p>字符串三大操作:1.查找关键字! 2.替换关键字 3.获取子字符串<br/>查找关键字:var index = str.indexOf("关键字");<br/>返回关键字所在位置!*如果没找到,返回-1!*<br/>indexOf:懒:只找第一个关键字位置!<br/>蠢:默认只能从位置0开始!<br/>var index = str.indexOf("关键字", from);<br/>from:开始查找的位置,从from开始向后查找<br/>一句话办几件事时,可以把表达式当值用!<br/>var str = "女神说要来,我草草的收拾了房间。结果她又说不来了。我说:我草";<br/>var index = -1;<br/>while((index = str.indexOf("我草", index + 1)) != -1){<br/>console.log("位置" + index + "发现关键字");<br/>}<p>从最后一个字符,向前找:只要关键字离结尾近,就用last<br/>var index = str.lastIndexOf("关键字", from);<br/>from:开始查找的位置,从from开始向前查找<br/>*返回的index完全相同!字符在数组中的下标是固定的!*<br/>2处修改:index从str.length开始;每次index要-1<p>2.获取子字符串:以下三个方法省略第二个参数,默认都是取到结尾!<br/>var subStr = str.slice(start, end + 1);<br/>start,end支持正负<br/>var subStr = str.substring(start, end + 1);<br/>用法同slice!唯一差别:不支持负值作为参数!<br/>var subStr = str.substr(start, *count*);<br/>JavaScript——>js字符串——><p>下午:<br/>按规律分割字符串:var subs = str.split("分隔符"[, count]);<p>鄙视题:var str = "no zuo no die";<p>课堂练习:判断字符的种类:unicode范围:<br/>48-57:0-9 数字字符<br/>65-90:A-Z 大写字母<br/>97-122: a-z 小写字母<br/>19968-40869:汉字<p>什么是模式匹配:可以设置查找或替换的规则!<br/>何时使用模式匹配:要查找的关键字可能发生有规律的变化。<br/>如何使用模式匹配:1.先定义模式:/关键字/模式<br/>比如:var reg = /no/ig; no是要查找的关键字原文,不加""<br/>i表示忽略大小写! g表示全局查找和替换!<p>String类型中,提供了专门支持模式匹配的API!<br/>按模式*替换*关键字:str = str.replace(reg, "新值");<br/>默认replace仅替换第一个关键字!<br/>要想全局替换,要在模式中定义“g”<p>获得*所有*关键字的*内容:var kwords = str.match(reg);<br/>只能取得关键字的内容,无法确定每个关键字的位置!<br/>kwords.length:找到的关键字个数!<br/>*如果未找到,返回null!*<br/>只要有可能返回null!都要先判断 !=null,再处理!<p>SetupRegexBuddy.exe 全部默认安装<p>var index = str.search(reg); 和indexOf完全相同!<br/>indexOf不支持模式查找!search其实是indexOf的模式查找版<p>今后在网页中只要处理字符串的格式,就要用正则表达式<br/>*正则表达式*<br/>什么是正则达表示:字符串中字符出现的规律<br/>何时使用正则表达式?验证字符串格式,查找关键字,替换关键字<br/>比如:银行卡查询密码:6位数字<br/>用户名:字母,数字,_的组合<p>正则表达式:<br/>选择符号:[所有备选字符]:[去草],必须多选一使用<br/>一个[],只能代表一位字符的规则<br/>[^xxxx]:表示出了xxxx都行!反义。注意必须放在[]中的第一个位置,否则变为普通字 <br/>符匹配。<p>-符号:字符的范围:备选字符是连续的范围!<br/>比如:[0-9] [a-z] [A-Z] [a-zA-Z]//-可以局部使用<br/>汉字范围:[u4e00-u9fa5]<p>预定义字符集:使用简化的符号,定义常用字符集<br/>比如:[0-9] ——> d [a-zA-Z0-9_] ——> w 空字符 ——> s<p>如果规则正文中出现特殊符号,用转为原文<p>.一个人一字符!<br/><br/>数量词:规定前边一个字符出现次数的两次<br/>语法:{min,max}<br/>{num}:固定长度<br/>{min,}:至少min个,多了不限<br/>手机号:+86s1[3578]d{9}<br/>用户名:w{6,8}<p> <p>day08 <br/>回复:<br/>[]:备选字符集,只能多选一。一个[]只能匹配一位字符<br/>比如:我[去草]:我去 我草 <br/>[]内:开头^:除了xx都行:[01235689] ——> [^47]<br/>-:表示备选字符的范围 :[a-z] [0-9] [A-Z]<p>预定义字符集:<br/>[0-9] ——> d<br/>[a-zA-Z_] ——> w<br/>s:空字符:
空格<p>量词:修饰前一位字符出现的次数<br/>{min,max}:最少min个,最多max个<br/>{min,}:最少min个,最多不限制<br/>{num}:固定num个<p>比如:验证座机号码:d{3,4}-d{7,8}<p>正课:<br/>特殊数量词:+ * ?<br/>?:可有可无,对多只能出现一次<br/>比如:我了?去: 我去 我了去 我了个去X 我了了去X<p>*:可有可无,不限制出现次数<br/>比如:点亮我生命的火*:<br/>点亮我生命的<br/>点亮我生命的火<br/>点亮我生命的火火火<p>+:至少出现一次!不限制出现次数<br/>比如:点亮我生命的火+:<br/>点亮我生命的火<br/>点亮我生命的火火火<p>如果正文中出现+?*,都要用转义<p>():分组:改变模式的匹配顺序<br/>比如:验证身份证号:d{15}(d{2}[0-9xX])?<br/>验证手机号:(+86)?s+1[3578]d{9}<p>^:整个正则表达式的开头,表示以xxx开始<br/>$:整个正则表达式的结尾,表示以xxx结束<p>?= 预判,前一个字符之后,必须紧跟xxx<br/>?! 预判,前一个字符之后,必须不能跟xxx<p>课堂练习:中文姓名:[u4e00-u9fa5]{2,6}<br/>电子邮件:w+@w+([-]w+)*(.w+)+<br/>其中:w+([-]w+)* —— 匹配域名<br/>一个以上的字母,后可跟“-字母”,可有可无<br/>(.w+)+<br/>“.字母”组合至少出现1次<p>RegExp对象:专门封装一条正则表达式,提供使用正则表达式的常用API<br/>如何使用RegExp对象:1.创建 2.调用API<br/>v如何创建正则表达式对象:ar regExp = /正则表达式/ig;<br/>API:<br/>验证:var boolean = regExp.test("被检查的字符串");<br/>如果验证通过:返回true;否则返回false<br/>验证 vs 查找:<br/>验证要求完整匹配!查找要求部分匹配!<p>**test方法默认:只要找到就返回true!**<br/>正则表达式前加^,后加$<p>查找:exec:查找关键字的位置,又能找到关键字的内容<br/>indexOf不支持正则,search支持正则,每次只能找1个<br/>match所有内容,但得不到位置!<br/>var arr = regExp.exec("被查找的内容");<br/>arr[0]:找到的关键字内容<br/>arr.index属性:找到的关键字的位置<br/>exec方法每次只能找1个,但是每次自动修改regExp对象的lastIndex属性!<br/>regExp对象的lastIndex属性:表示下次开始匹配的位置!<p>查找:仅判断有没有,或者仅查找位置:str.indexOf()<br/>支持正则表达式:str.search()<br/>仅所有关键字的内容:str.match()<br/>即找位置,又找内容:regExp.exec()<p>/正则表达式/<br/>var regExp = new RegExp("\d{6}", "ig"); 动态创建正则表达式<br/>强调:所有都要改为\<p>贪婪模式: .+ .*,默认先匹配整个字符串,再缩小范围!<br/>懒惰模式: (.+?) (.*?),从第一个字符开始,向后扩展范围<p>下午:<br/>从正则表达式匹配的内容中,取一部分:RegExp.$n<br/>n:正则表达式中第n个分组,其实就是第n个圆括号<br/>强调:分组从1开始<br/>必须通过RegExp类型,直接调用$n,不能使用对象!<p>String对象与正则表达式<br/>str = str.replace(/正则表达式/ig, "替换值");<br/>var arr = str.match(/正则表达式/ig); str.search()<br/>str.split(/正则表达式/);<p>trim功能:去除字符串开始和结尾的空格。中间空格不去除!<br/>对输入字符串的处理,多数要先清除开头结尾空格,再处理<br/>IE8不支持trim()方法!<br/>自定义trim()方法:<br/>function trim(str){<br/>var regExp = /(^s+)(s+$)/g;<br/>str = str.replace(regExp, "");<br/>return str;<br/>}<p>String总结:所有的API都无法修改原字符串,都会返回新的字符串<br/>所有StringAPI都需要用变量保存结果!<br/>str.length 字符个数<br/>str = str.toUpperCase()/toLowerCase()<br/>查找关键字:var index = str.indexOf("关键字"[, from])<br/>var arr = str.match(/正则表达式/g);<br/>获得子字符串:var substr = str.slice(start, end + 1);<br/>str.substring(start, end + 1);<br/>str.substr(start, count);<br/>替换:str = str.replace(/正则表达式/g, "替换值");<br/>获得指定位置的字符:var char = str.charAt(index);<br/>str[index];<br/>字符编码转码:var code = str.charCodeAt(index);<br/>var char = String.fromCharCode(code);<p>RegExp对象总结:<br/>var reg = /正则表达式/ig;<br/>var reg = new RegExp("正则表达式", "ig");<br/>*其中所有的都要改为\!*<p>验证str中时候包含reg匹配的关键字:<br/>var boolean = reg.test(str);<br/>*强调:完整验证,都需要在正则表达式前加^后加$*<p>同时查询所有关键字的内容和位置<br/>while((arr= reg.exec(str)) != null){<br/>arr[0] ——> 找到的一个关键<br/>arr.index ——> 当前关键字的位置<br/>}<p>RegExp.$n:<br/>获得正则表达式中第n个分组(圆括号)匹配的子字符串<p>Math类型:封装了所有数学计算有关的API<br/>不能new!<br/>Math.PI<p>Math.round(num) ——> 四合五入取整<br/>Math.ceil(num) ——> 向上取整<br/>Math.floor(num) ——> 向下取整<p>Math.pow(底数, 幂);<br/>Math.sqrt(num);//平方根!<p>绝对值:Math.abs(num);<p>Math.max/min(值1, 值2, 值3, ...);<br/>取数组中的最大值:var max = Math.max.apply(Math, arr);<p>随机数:Math.random(); 0<=r<1<br/>任意min-max:<br/>Math.floor(Math.random() * (max - min +1) + min);<p>/*随机生成四位验证码*/<br/>//Step1:数组:所有字母、数字<br/>var codes = [];<br/>for(var i = 48; i <= 57; codes.push(i), i++);<br/>for(var i = 65; i <= 90; codes.push(i), i++);<br/>for(var i = 97; i <= 122; codes.push(i), i++);<p>function getCode(){<br/>var arr = [];<br/>for(var i = 0; i < 4; i++){//0-61之间取随机数<br/>var index = Math.floor(Math.random()*(60-0+1) + 0);<br/>var char = String.fromCharCode(codes[index]);<br/>arr.push(char);<br/>}<br/>return arr.join("");<br/>}<p>while(true){<br/>var code = getCode();<br/>var input = prompt("输入验证码:" + code);<br/>var reg = /^[a-zA-Z0-9]{4}$/;<br/>if(reg.test(input)){<br/>if(code.toLowerCase() == input.toLowerCase()){<br/>document.write("登录成功");<br/>break;<br/>}else{<br/>alert("验证码输入错误!");<br/>}<br/>}<br/>}<p>Date对象:封装一个时间点数据,提供对时间、日期的常用API<br/>创建:var date = new Date();<br/>1.创建Date类型对象; 2.自动获得浏览器当前时间点!<br/>自定义时间:var date = new Date("2015-6-9 16:47");<br/>1.创建Date类型对象; 2.自定义一个具体时间点<p>*Date对象中,<br/>保存的是从1970年1月1日 0:00:00到现在的毫秒数<br/>var date = new Date();<p>API:<br/>1.每个分量都有一对get/set方法,获取/设置该分量的值!<br/>2.命名:年/月/日 没有s,时,分,秒 有s<br/>3.取值、赋值:除了每月中的日之外,其余都是从0开始,到-1结束<br/>每月中的日,从1开始,带31结束<br/>月:取值时,要+1修正;赋值是,-1修正<br/>星期://日 一 ............ 六<br/>//0 1 6<p>日期计算:两日期对象相减,得到毫秒数<br/>时间做+:var nowMs = date.getTime(); 返回时间毫秒数<br/>var nextMs = nowMs + 5*60*1000;<br/>var next = new Date(nextMs);<br/>使用毫秒做计算,不改变原时间对象!需要重新封装时间对象<br/>最大仅能算到“天数”。再算“月数”,无法确定每月天数。<p> <p><br/>day09<br/>回顾:<br/>Date对象:内部封装了一个毫秒数<br/>创建日期对象:<br/>var date = new Date("2016/7/4");PPT上 new Date("2016-7-4");仅兼容chrome<br/>API<br/>1.每个分量都有一对get/set方法<br/>2.命名:年月日星期 不带s;时分秒带s<br/>3.值范围:月中的日:1-31;其他:0-减1<p>计算:1.两日期相减,得到毫秒数<br/>2.日期+/- 天小时分秒:用毫秒<br/>3部:1.var ms = date.getTime();<br/>2.ms = ms +/- 毫秒数<br/>3.var newDate = new Date(ms);<p>正课:<br/>3.任意分量的计算:<br/>先取出分量值,做计算,再set回去!<p>var now = new Date();<br/>var day = now.getDate();//4<br/>day -= 10;//-6<br/>now.setDate(day);<br/>document.write(now);<p>date.setXXX();1.自动调整进制<br/>2.*直接修改原日期对象*<br/>如何保留原日期对象?先new出新Date对象,再set<br/>var newDate = new Date(oldDate.getTime());<p>日期格式转换:<br/>date.toLocaleString();//获得日期和时间的本地格式<br/>date.toLocaleDateString();//仅获得日期部分的本地格式<br/>date.toLocaleTimeString();//仅获得时间部分的本地格式<p>日期格式转换:都要自定义format(date)方法!<br/>function format(date){<br/>var week = ["日", "一", "二", "三", "四", "五", "六"];<br/>var y = date.getFullYear() + "年";<br/>var m = date.getMonth() + 1 + "月";<br/>var d = date.getDate() + "日";<p>var w = " 星期" + week[date.getDay()];<p>var h = date.getHours();<br/>var am = h >= 12 ? " 上午 " : " 下午 ";<br/>h = h > 12 ? h - 12 : h;<br/>h = h < 10 ? "0" + h : "" + h;<p>var mi = date.getMinutes();<br/>mi = mi < 10 ? "0" + mi : "" + mi;<p>var s = date.getSeconds();<br/>s = s < 10 ? "0" + s : "" + s;<p>var str = y + m + d + w + am + h + ":" + mi + ":" + s;<br/>return str;<br/>}<p>Number类型 API:<br/>num.toFixed(n); 按n位小数四舍五入,*返回一个字符串*!<br/>何时使用:在计算之后,显示结果是,*最后调用toFixed方法*<br/>vs Math.round(num):只能取整 返回一个数Number<p>num.toString(n):按n进制输出数字的字符串格式<p>错误处理:<br/>什么是错误处理:导致程序运行停止的运行时异常状态<br/>什么是错误处理:在出现异常状态是,保证程序不停止的机制<br/>如何错误处理:<br/>错误类型:Error类型:所有错误对象的父类型<br/>6种子类型:EvalError,<br/>RangeError:参数超出范围<br/>比如:num.toFixed(n) n<0 抛出RangeError<br/>ReferenceError:引用错误:找不到对象<br/>比如:只要使用未声明的变量时,都要抛出ReferenceError<br/>SyntaxError:语法错误!修改源代码就可以解决!<br/>TypeError:错误的使用了类型和类型的方法!<br/>URIError:URI错误<br/>如何处理错误:<br/>try{<br/>可能出错的代码<br/>}catch(err){只要抛出错误,都要创建一个Error对象<br/>错误处理的代码<br/>1.获得错误信息:err.name 类型<br/>2.根据错误的类型,执行不同的处理<br/>}[finally{可有可无<br/>//程序中使用了大对象!一样要在finally中主动释放<br/>无论是否出错,都必须执行的代码<br/>}]<p>能用if...else解决的问题,就不用try...catch!<br/>何时使用try...catch?try...catch处理的是无法预料的问题!<p>主动抛出异常:如何告知方法调用者出错?<br/>thow new Error("自定义的错误信息");<p>下午:<br/>Function对象:<br/>1.以声明方式定义方法:放前放后无所谓<br/>function 方法名(参数列表){方法体;return 返回值}<br/>2.以创建对象方式定义方法:必须定义在使用之前!<br/>var 方法名 = new Function("参数1", ..., "方法体;return 返回值");<br/>只有声明方式的方法定义才被提前解析!——方法声明提前<p>重载:方法,根据传入的参数列表不同,执行不同的任务<br/>js支不支持重载:语法不支持,但是可以通过 arguments对象 模拟重载效果<p>arguments对象:方法对象中保存所有参数的类数组对象<br/>类数组对象(object like array):长的像数组的对象<br/>*方法内,自动创建!直接使用!*<br/>arguments.length:保存变量的个数<br/>arguments[i]:访问传入的第i + 1个变量<p>3.使用匿名函数赋值的方式定义方法:<br/>匿名函数:没有方法名的函数定义!<br/>var compare = function(a, b){return a-b;}<p>鄙视题:js中方法定义的方式有几种:3种!<br/>A.function compare(a, b){return a - b}<br/>**************************************************************************<br/>B.var compare = function(a, b){return a - b;}<br/>C.var compare = new Function("a", "b", "return a- b;");<br/>D.var compare = new Function(a, b, return a- b;); X<p>function isEmpty(str){<br/>if(str === undefined){<br/>return true;<br/>}else if(str == null){<br/>return true;<br/>}else{<br/>var reg = /^s*$/;<br/>return reg.test(str);<br/>}<br/>}<p>var ltrim = function(str){<br/>var reg = /^s+/;<br/>return str.replace(reg, "");<br/>}<br/>var rtrim = function(str){<br/>var reg = /s+$/;<br/>return str.replace(reg, "");<br/>}<p>匿名函数2个用途:<br/>1、回调函数:函数何时执行,程序员不需要控制!<br/>由所在环境执行!<br/>比较器!<br/>//var compare = function(a, b){return a - b;} arr.sort(compare);<br/>arr.sort(function(a, b){return a - b;})<br/>事件处理函数:onclick = "calc(12)";<br/>2、自调函数:匿名函数自己调用自己!<br/>当函数不需要重复使用时,使用匿名函数自调。<br/>语法:<br/>(function(参数...){<br/>方法体;<br/>})(参数值...);<br/>在函数定义的位置立即执行!<p>闭包:函数外使用了不属于自己的局部变量<br/>何时使用闭包?保护局部变量<p>day10<br/>回顾<br/>1. 闭包<br/>判断闭包3特点:<br/>1. 嵌套函数<br/>2. 内层函数操作了外层函数的局部变量<br/>3. 外层函数将内层函数返回到外部<br/>被全局变量保存住<br/><br/>判断闭包执行结果:<br/>*1. 外层函数被调用几次,就有几个受保护的局部变量副本<br/>2. 反复调用来自一个闭包的函数,受保护的局部变量就变化几次<br/><br/>正课:<br/>1. 面向对象<br/>1. 创建自定义对象<br/>2. ****继承<br/><br/>1. 面向对象:在程序中都是用一个对象来描述现实中一个具体的东西;<br/>现实中的一个东西都包含属性和功能:<br/>属性:描述一个东西特点的变量<br/>功能:东西可以执行操作<br/>什么是对象:封装多个数据的存储空间<br/>什么是自定义对象:封装现实中一个东西的属性和功能的存储空 <br/>间。现实中东西的属性会成为对象中的属性变量。现实中的东西的功能,会成为对象中 <br/>的方法(函数)<br/><br/>2. 创建自定义对象:3种方式:<br/>1. var obj = {'属性名1':值1,<br/>'属性名2':值2,<br/>...<br/>'功能名1':function() <br/>{...}};<br/>js中一切都是对象!所有对象的底层都是hash数组<br/><br/>属性:如何访问属性:2种:obj.属性名 obj["属性名"]<br/>访问对象中不存在的属性<br/>(访问数组中不存在的下标):不会出错,返回undefined<br/>强行给不存在属性赋值,不报错!js会自动创建同名属性<br/><br/>如何判断某个对象是否包含指定成员:3种<br/>1. obj.hasOwnProperty("成员名");<br/>2. "属性名" in 对象<br/>如果找到,返回true,否则返回false<br/>3. 直接使用 obj.属性名 作为条件:<br/>arr.indexOf !== undefined<br/>如果不包含,返回undefined ————> false<br/>如果包含,返回值或function ————> true<br/>何时省略:判断方法是否存在时,可省略 !==<br/>如果确定属性值一定 <br/>不是null, 0, "", NaN 也可省略<br/><br/>方法:如何在方法中,访问当前对象自己:<br/>****this关键字:运行时,指代正在*调用*方法的对象<br/>(.前的对象)<br/>this本质是window下唯一的一个指针,指向当前正在 <br/>调用方法的对象<br/><br/>如何在方法内,访问当前对象自己的属性:this.属性名<br/>**在方法内访问当前对象自己的属性,必须用this.属性 <br/>名<br/>省略this,默认访问活动对象和window中的变量(闭 <br/>包除外)<br/><br/>***this和定义在哪无关!仅和调用时使用的当前对象有 <br/>关<br/>***如果无主的调用或复制,默认this都是window!<br/><br/>PM: <br/>正课:<br/>1. ***面向对象:继承<br/>面向对象三大特点:封装 继承 多态<br/>封装:将描述同一个东西的属性和方法,定义在一个对象中<br/>继承:父对象中的属性和方法,子对象可直接使用<br/>多态:同一个对象,在不同情况下,呈现不同的状态<br/>重载:同一方法名,传入参数不同,执行不同的操作<br/>重写:子对象觉得父对象的成员不好用,可自己定义一 <br/>个,覆盖父对象的成员<br/><br/>创建对象:3种:<br/>1. 对象直接量<br/>var obj = {"属性名":值, ..., "方法名":function(){...}};<br/><br/>2. var obj = new Object();//创建一个空对象<br/>obj.属性名 = 值;<br/>obj.方法名 = function(){... this.属性名 ...};<br/><br/>3. 利用构造函数*反复*创建*相同结构*的对象<br/>构造函数:描述一类对象结构的特殊函数<br/>2步:<br/>1. 定义构造函数<br/>function 构造函数名|类型名(属性参数1, ...){<br/>this.属性名 = 属性参数1;<br/>//在当前正在创建的对象中创建一个属性名<br/>//赋值为属性参数1的值<br/>...<br/>this.方法名 = function(){<br/>...this.属性名...<br/>}<br/>}<br/>2. 利用构造函数创建对象<br/>var obj = new 构造函数名|类型名(属性值1, ...);<br/>new:1. 创建一个空对象:new obj = {};<br/>2. 利用空对象,调用构造函数<br/>构造函数在空对象中添加属性和 <br/>方法<br/>3. 设置新对象的 __proto__ 指向构造函数的 <br/>prototype对象<br/>4. 返回新对象的地址<p>继承:js中一切继承都是用原型对象实现的!<br/>原型对象:每个函数对象都有一个原型对象<br/>构造函数的原型对象负责保存所有子对象共享的成员!<br/>建议:所有子对象共享的方法,都应定义在构造函数的原型对象中。——— <br/>—避免重复定义方法对象,浪费内存。<br/>说明:其实所有内置类型的API都是定义在类型.prototype<p>扩展对象属性:2种扩展:<br/>1. 扩展共有属性:通过构造函数.prototype添加的属性<br/>2. 扩展自有属性:通过某一具体子对象添加属性<br/>判断自有属性或扩展属性:<br/>1. 判断自有属性:obj.hasOwnProperty("属性名");<br/>2. 判断共有属性:"属性名" in obj && !obj.hasOwnProperty("属性名")<br/>在原型对象关系中包含 且 子对 <br/>象自己*没有*<br/><br/>删除属性:delete 对象.属性名<br/>*仅能删除当前对象自己的属性,无法删除共有属性<br/>全局变量:3种<br/>var n = 1; window.n = 1; window["n"] = 1;<br/>不能delete 不能delete 能delete<p>原型链:由各级对象的 __proto__ 逐级继承形成的关系<br/>获得任意对象的父级原型对象:Object.getPrototypeOf(子对象) =》子对象.__proto__<br/>检查对象的父对象:父对象.isPrototypeOf(子对象);<p><br/>day11<br/>面向对象:封装 继承 多态<br/>1. 创建对象:3种:4种:<br/>1. 直接量:var obj = {"属性名":值, ..., "方法名":function(){}};<br/>__proto__ ————> Object.prototype<br/>2. new关键字:var obj = new Object();<br/>obj.属性名 = 值;<br/>...<br/>obj.方法名 = function(){}<br/>3. 使用构造函数反复创建相同结构的对象:2步<br/>1. 定义构造函数:<br/>function 构造函数名(属性参数, ...){<br/>this.属性名 = 属性参数;<br/>if(!构造函数名.prototype.方法名){<br/>构造函数名.prototype.方法名 = <br/>function(){}<br/>}<br/>}<br/>2. 使用new创建对象同时,调用构造函数:<br/>var obj = new 构造函数名(属性值, ...);<br/>4. Object.create(父对象, {扩展属性的列表对象});<p>2. this:指代当前正在调用方法的对象<br/>this和定义在哪无关!仅和调用时使用的对象有关!<br/>所有无主(不用var赋值的变量,匿名函数)都是window的<p>3. 原型,原型链,继承:<br/>原型:保存所有子对象共有属性和方法的对象!<br/>所有函数都有prototype,指向自己的原型对象<br/>所有对象都有 __proto__ ,指向自己父级原型对象<br/>所有原型对象都有constructor,指回原型对应的构造函数<br/><br/>原型链:所有父子级对象间由 __proto__ 形成的多级引用关系<br/>————>*多级*继承<br/><br/>原型相关API:<br/>1. 判断自有属性和共有属性:<br/>1. 判断自有:obj.hasOwnProperty("属性名");<br/>2. 判断原型链上的属性:2种<br/>判断不包含:if(!("属性名" in obj/原型))<br/>if(obj.属性名 === undefined)<br/>if(!obj.属性名)<br/>3. 仅判断共有:必须满足两个条件<br/>!obj.hasOwnProperty("属性名") && obj.属性名<br/>2. 获得任意对象的原型:<br/>obj.__proto__ X<br/>Object.getPrototypeOf(obj)<br/>3. 判断父对象是否在子对象的原型链上<br/>父对象.isPrototypeOf(子对象)<br/><br/>***检测一个对象是不是数组类型:4种:<br/>1. Array.prototype.isPrototypeOf(obj);<br/>2. obj instanceof Array<br/>对象 是不是 构造函数 的实例<br/>3. obj.constructor == Array 仅判断直接父级<br/>4. 利用当前对象,强行调用原始的toString方法<br/>Object.prototype.toString.call(obj) == "[object Array]"<br/>apply(obj)<br/>继承:<br/>为什么要继承:代码重用!节省空间!<br/>1. 直接继承对象:想方设法修改对象的 __proto__ 属性<br/>3种:<br/>1. 仅修改一个对象的 __proto__<br/>Object.setPrototypeOf(子对象, 父对象);<br/>2. 通过修改构造函数的原型对象,实现批量修改后续子对象的继承关系。<br/>构造函数.prototype = 父对象<br/>强调:仅影响之后创建的对象的继承关系<br/>之前创建的对象依然继承旧构造函 <br/>数.prototype<br/>3. var obj = Object.create(父对象[, {属性列表}])<br/>创建一个空对象,<br/>继承父对象中的属性,<br/>继承同时可再扩展属性和方法<br/><br/>2. 仅继承结构:模拟java中的继承<br/>function 父类型构造函数(属性参数1, 属性参数2){<br/>this.属性1 = 属性参数1;<br/>this.属性2 = 属性参数2;<br/>}<br/><br/>function 子类型构造函数(属性参数1, 属性参数2, 属性参数3){<br/>父类型构造函数.call(this, 属性参数1, 属性参数2);<br/>this.属性3 =属性参数3;<br/>}<br/><br/>var obj = new 子类型构造函数(值1, 值2, 值3);</script>