zoukankan      html  css  js  c++  java
  • javascript笔记

    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样式,事件的统一标准!

    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脚本块的元素
    <script>中脚本块何时运行?随网页加载,解释执行
    <script>中都要使用js语法!
    html元素的事件“属性”中:
    什么是事件?元素可以根据鼠标或键盘的不同操作相应不同的交互行为。
    charset必须和文件的存储编码一致
    <script>解释执行,读到执行。先读先执行。——<script>放置的先后顺序影响程序结
    果。
    优化:放在body的最后

    一次定义处处使用,一次修改处处生效!
    解决:凡是重复编写的代码块,都要封装为一个方法
    方法:执行一个专门功能的一组代码的序列。
    一般定义在<head>下的<script>中
    语法:function 方法名(){重用的代码块}
    *不调不执行*

    调试:bug? debug:解决问题,排除错误
    只要没反应或效果没出来就是出错!——>F12
    查看错误原因——>定位错误位置!
    <script>脚本块中的错误,仅影响“当前脚本块”中出错“位置之后”的脚本执行。
    不影响<script>之外的其他元素加载或脚本执行。
    function中的错误:只有调用方法是才触发!

    页面内部脚本块问题:仅当前页面可用!
    解决:外部.js文件!
    什么是.js文件:专门保存js脚本源代码的文件。
    源代码都要放到js解释器才能执行。
    如何使用.js文件?2步:1、创建.js文件,编写源代码 2、在页面引入外部.js文件
    内外部同名方法,解释执行!

    pm:
    JavaScript=ECMAScript(核心语法)+DOM(操作网页内容)+BOM(操作浏览器
    窗口)

    ECMAScript(核心语法)
    *区分大小写*
    *字符串必须用引号(单双都行)包裹*
    *每条语句结尾都建议有分号*

    语句:让程序可以做一件事的一行命令
    脚本块:多行语句的序列
    程序:让计算机可以模拟执行人类的想法!
    注释:不会被解释执行或显示的代码说明——给程序员看的
    注释也占网页流量!生产环境必须去掉!
    HTML注释:<!---->
    CSS注释:/**/
    JS注释://单行注释 /*多行注释*/

    *变量*
    什么是变量?内存中专门存储数据的空间
    程序都是在内存中运行
    任何程序:IPO:Input Process Output
    数据 数据 数据
    何时使用变量?只要在程序中临时存储数据,都要放在变量中
    怎么使用变量?声明,命名,初始化和使用
    声明:在内存中开辟一个存储空间,并且起一个名字
    怎么声明?var 变量名;
    赋值:将等号右边的数据,装入等号左边的变量中!
    如果未赋值:js默认赋值为undefined

    命名规则:见名知意
    保留字、关键字不能当变量名
    保留字:js中已经占用的特殊意义的关键字
    使用:使用变量名等于直接使用变量中存储的数据
    +:拼接多段文字为一句话!

    常量:一旦创建,值不可改变的特殊变量
    如何使用常量:const 常量名=常量值;

    强调:只有等号可以向变量中存入新值。普通运算不会改变变量的值。只是使用变量的
    值。
    只要带var就是声明,只要声明就会开辟内存空间、
    js中新同名变量的空间会替换旧的空间。
    有几个var,就会创建几个存储空间。

    数据类型:变量中存储的数据类型。
    js是弱类型:变量本身没有类型。只有变量中的值才有类型。
    一个变量,可以反复保存不同类型的数据。
    为什么要有数据类型:现实中所有数据根据用途不同,都分为不同数据类型。

    原始类型:数据保存在变量本地!
    number类型:表示一切用于比较或数学计算的数字
    程序中数字分整数、浮点数(现实中的小数)
    js中一切数字都用number保存,不分整数类型和小数类型
    如何定义number类型?不带引号的数字字面量
    程序中数字类型的舍入误差:程序中不能准确表示1/10,就好像现实中不能准确表示
    1/3一样!
    如何修正:按指定位数四舍五入:数字.toFixed(小数位数)
    今后计算结果小数位数超长,说明碰到舍入误差。按位四舍五入。
    精度计算不要用JavaScript

    string类型:一串字符的序列!
    Unicode:对所有语言文字中的字符编号
    Why“因为计算机只处理数字,无法处理文字。
    计算机处理unicode编号,就等效于处理编号对应的文字。
    转义字符:专门表示非打印字符以及特殊符号
    如何使用转义字符:特殊符号 比如: 换行 、 tab键
    如果字符串中包含与语法相冲突的特殊字符,要用转为原文

    *字符串变量的内容一旦创建补课费改变!如果改变,只能创建新字符串,抛弃旧字符串
    。*
    鄙视题!
    var str = "Hello";
    str = str + “Word”;
    3个!

    boolean类型:仅有两个值的特殊数据类型:true,false
    何时使用boolean?只要一个值只有真假两种情况,就用boolean类型

    undefined类型:表示一个变量仅声明过,但从未赋值。所有未赋值的变量,默认值都
    是undefined。
    undefined类型的值还是undefined!

    原始类型的大小:
    number:整数4字节,浮点8字节
    string:每个字符两字节


    day02
    回顾:
    JavaScript:ECMAScript(核心语法)
    DOM(操作网页内容)
    BOM(操作浏览器窗口)
    ECMAScript:标准
    Netscapt:javaScript Microsoft:JScript

    变量:内存中存储数据的一块空间
    一切数据必须存在变量中
    声明:var 变量名——>在内存中开辟一块空间
    赋值:变量名=值——>将值保存到左边的变量空间中备用
    使用:使用变量名,就等效于直接使用变量中的数据

    数据类型:
    why:存储空间的大小,用途
    原始类型:数据保存在变量本地
    number string boolean undefined null

    string:字符串内容一旦创建不能改变
    var str = "Hello";
    str = str + "World";
    3个!

    正课:
    数据类型间的转换:
    隐式转换:程序自动转换数据类型(坑)
    弱类型:1、变量声明是不必限定数据类型,今后可能保存任何数据类型
    2、数据类型间可以自动类型转换
    仅考虑+:只要有字符串参与,一切类型都加""变为字符串
    如果没有字符串,都转换为数字计算:其中true——>1 false——>0

    强制转换:程序员通过调用专门函数,手动转换类型
    2 string:x.toString();——>将x转为字符串类型
    2 number:Number(x);——>将任意类型转为number类型
    string——>number:
    转为整数:var num = parseInt("str");
    读取字符串中的整数部分
    1、从第一个字符向后读。
    2、如果碰到第一个数字字符,开始获取数字,再次碰到不是数字的字符,停
    止读取
    3、如果开头碰到空格,忽略
    4、如果碰到的第一个非空格字符,不是数字,说明不能转——>NaN: Not
    a Number
    什么是NaN:不是数字(内容)的数字(类型)
    转为浮点数:var num = parseFloat("str");
    用法和parseInt全完相同
    唯一差别:parseFloat认识小数点

    prompt("提示信息"):专门用于请求用户输入数据,收集数据的对话框!
    var str = prompt("提示信息");
    *凡是从页面上获得的数据,都是字符串!必须先转换再计算*

    什么是运算符:程序模拟人类运算的特殊符号
    算数运算:-任意类型做-,都会被转为数据类型
    如果有参数,不能自动转换为数字,则返回NaN
    如果除数为0:Infinity——>无穷大
    typeof(x):判断任意数据的类型
    被除数%除数——模运算:被除数/除数,取除不尽的余数
    何时用:限制一个数不能超过某个最大范围时

    递增/递减运算:i++ ==> i = i +1;
    i++单独用:++放前放后,效果一样:i++ ==> ++i;
    i++出现在表达式内部:
    前++,前+1,再参与表达式
    后++,先用旧值参与表达式。表达式之后再+1

    关系运算:判断大小!条件判断中使用
    结果:成立:true,不成立:false
    *自带隐式类型转换*
    字符串参与运算:从第一个字符开始,取出每个字符 PK unicode编号
    "Hello" H e(101)
    "Hi" H i(105)
    关系运算中:任何类型和数字比较,都转为数字,再比较
    布尔类型参与关系运算,始终转为数字比较

    PM:
    关系运算:现将参与判断的数据,强转为相同类型,再比较
    字符串比较:
    undefined做==比较:
    undefined类型,从null类型继承来的
    undefined值被自动转换为null!
    undefined == null ——>true
    ===严格相等:不带自动类型转换的相等比较!
    类型和值必须都相等!才返回true。
    严格相等最初就是为undefined和null设计的
    只要不确定比较的类型,又不希望自动类型转换时,就用===

    NaN做==:
    isNaN(x):专门用来判断一个数据是不是NaN
    如果是NaN返回true;如果不是NaN返回false

    只要不能转换为数字的,都返回true
    只要能自动转换为数字的,都返回false
    关系运算中"",可以自动转换为false或0
    总结:1、普通数据,先转换为相同类型,再比较
    2、undefined,就用===
    3、NaN,就用isNaN(x)

    逻辑运算:基于多组关系运算,得出一个结论
    &&:而且
    ||:或者
    !:非,颠倒true和false,今后只要颠倒判断结果,就用!

    短路逻辑:只要前一个判断足以得出最终结论,则后续条件不执行!

    验证是不是汉字:>="u4E00" && <="u9FA5"
    闰年的判断公式:(year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)

    位移:n << m ——>n*(2的m次方)
    n >> m ——>n/(2的m次方)

    赋值运算:赋值运算结果就是等号右边表达式的结果
    扩展的赋值表达式:对已有的数据计算的同时,将结果再存回变量
    何时使用:修改原变量值

    三目运算:根据不同条件,动态返回不同结果!
    三目:至少需要3个表达式。
    语法:
    一个条件,二选一:条件?当条件满足时返回的值:当条件不满足时返回的值
    多个条件,多选一:
    条件1?条件1满足时的值:
    条件2?条件2满足时的值:
    条件n?条件n满足时的值:
    默认值;
    需求1:2个数中取最大的
    var score1 = 100;
    var score2 = 80;
    var result = score1 > score2 ? score1 : score2;
    注意:后一个条件中不用包含否定前一个条件的关系判断。
    因为,进入后一个条件隐含的条件就是前一个条件不满足。


    day03
    NaN == NaN? false NaN和任何数据比较,永远返回false
    今后只要可能判断NaN时,用isNaN(x)
    var str = "Hello";
    str > 10? str > 10000? false
    NaN NaN
    关系运算中,字符串比数字,字符串转为数字!

    注意:逻辑运算中,不要急于将第一个条件之后的++/--提取出来

    使用变量错误的情况:*没声明的变量,只要使用就出错!*
    var name;
    console.log(Name);//程序运行错误错误!会导致程序停止
    console.log(name);//undefined1

    函数(方法):封装执行一项专门任务的步骤的代码序列
    何时定义方法?只要发现一段代码重复使用,就封装为方法
    语法:声明
    function 方法名(参数列表){
    方法体:步骤清单
    return 返回值;
    }
    调用:方法名(参数值列表);
    参数:方法内独有的变量。接收传入数据,在方法内处理。参数让方法变灵活!
    如何声明方法参数:不用var!
    参数何时被创建?只有方法被调用时才自动创建
    返回值:方法执行完成后,由方法返回的数据
    定义返回值:不用再声明变量,直接用return值!
    为什么定义返回值:因为调用方法的人需要明确的返回结果。
    返回值主要给调用者使用。
    return:本意退出方法!
    退出同时,可返回数据!
    可以再任何需要的地方,调用方法执行返回值;
    带返回值的方法,使用时,等效于直接使用返回值数据。

    作用域:一个变量的可用范围!
    全局作用域:直接放在全局作用域中的变量,叫全局变量
    只要希望所有作用域公用的变量都要声明在全局作用域
    window
    局部(函数)作用域:声明在方法内部的变量或方法参数的变量都叫局部变量
    值传递:将一个变量的值赋值给另一个变量,其实将原变量中的值,复制一份给新变量

    js中一切赋值都是值传递!

    对未声明的变量赋值:js会自动在全局创建该变量!

    函数作用域和变量作用域完全一样
    函数作用域在调用方法时创建,方法执行完立刻销毁!

    PM
    问题:
    方法参数:依据方法内部的处理逻辑至少需要几个数据才能正常执行。
    方法参数和外部定义了了那些变量没有任何关系。
    方法参数作用:1、接收外部传入数据,在方法内处理
    2、规定调用方法的人必须提供哪些参数!

    方法的返回值:根据方法调用者的需要! 如果方法调用者需要明确返回一个结果,就定
    义返回值!否则,可以不定义返回值!
    何时必须使用变量接住?方法的返回值,后续程序可能反复使用!

    鄙视题:
    var num = 0;
    function f1(num){
    var num = 100;
    console.log(num);
    }
    f1();
    console.log(num);
    //100 0

    正课:
    自定义函数:
    全局函数:ECMAScript定义了标准,由个浏览器厂商已经实现的函数。我们直接调用

    isNaN(x) parseInt/Float(x)

    encodeURI( kword ):将url中的非法字符转为单字节符号——编码
    decodeURI( kword ):将encodeURI转后的字符串,转换为原文——解码
    unicode编码:每个字符2字节
    utf-8:字母、数字单字节,汉字3字节

    url规定参数值中,再次出现保留字,就是非法:
    保留字:/ ? $ : 等

    encodeURIComponent( kword );既能对多字节非法字符编码,又能对单字节非法字符
    编码——今后只使用component就够了
    何时使用?将数据通过url发送时,都要先编码再发送
    decodeURIComponent( kword );对encodeURIComponent()编码的字符串解码。收
    到编码后的字符串后,都要先解码,再处理。

    eval():专门执行字符串格式代码

    程序结构:3种:顺序;分支;循环

    程序:IPO
    需求:找名词——>程序中的数据
    两类:输入数据
    输出数据
    分析处理流程:

    分支结构:程序运行过程中,可以根据不同的条件,执行不同的任务。
    分支结构:if...结构:1件事,要么做,要么不做
    if...else...结构:2件事,二选一执行
    else if结构:多件事,多选一执行



    day04
    回顾:
    方法参数:方法内处理逻辑必须的数据
    参数仅限方法内部使用!方法外无法访问方法的参数变量
    参数名称自定义!
    返回值:调用者是否需要获得方法的执行结果

    分支:if结构 1件事 可做可不做
    if...else... 2件事 必须二选一
    if...else if...[else...] 多件事 多选一执行

    正课:
    switch...case...多条分支,根据条件判断,选择执行
    switch...case...用的是严格相等,不带自动类型转换
    语法:swith(表达式){
    case 表达式1://如果表达式的值===表达式1的值
    代码段1;
    case 表达式n:
    代码段n;
    default://如果表达式的值和都有的case都不相等
    默认代码段;
    }
    运行机制:如果找到与表达式匹配的case,不但执行当前case下的代码,而且之后所有
    代码都被触发!
    switch(true){
    case socre >= 90: console.log("A");
    case score >= 80: console.log("B");
    case score >= 60: console.log("C");
    default: console.log("D");
    }
    break:退出当前结构;
    多条件公用同一套执行逻辑是,不加break。
    switch(true){
    case socre >= 90: console.log("A");break;
    case score >= 80: console.log("B");break;
    case score >= 60: console.log("C");break;
    default: console.log("D");
    }

    循环结构:程序反复执行同一套代码段。遇到结束条件,会结束执行。
    没有循环结束条件,永远循环呢执行——死循环

    循环三要输:
    1、循环条件:循环继续执行的条件。一旦循环条件不满足,循环立刻退出!
    2、循环变量:用于循环条件中做判断的变量。循环变量都会向着循环退出的趋势变化
    (不满足循环条件的趋势)——循环计数器
    3、循环体:每次循环要做的事情

    while循环:当满足条件时,就继续循环做...事
    语法:
    var 循环变量;
    while(循环条件){
    循环体;
    迭代变化循环变量;
    }
    break:退出当前结构
    while中何时用break:循环条件不满足之前,希望强行退出循环。
    如何使用break?可以放在任何需要退出循环的位置。

    随机数:Math.random();0<=n<1
    任意min——max之间取随机数
    公式:parseInt(Math.random()*(max-min-1)+min)

    do-while循环:先执行一次循环体,再判断是否继续!
    如果循环条件不满足,循环体至少可以执行一次!
    var 循环变量;
    do{
    循环体;
    迭代变化循环变量;
    }while(循环条件);

    *变量声明提前*:“相同作用域内”,var...不论出现在什么位置,解析时,优先提取到
    js开始位置“声明”!

    for:完全等效于while循环。
    循环变量变化规律固定,循环次数已知、固定
    for(声明并初始化循环变量;循环条件;迭代变化循环变量){
    循环体
    }

    continue:跳过本轮循环,继续执行下一轮循环

    遇到复杂问题:
    先用简单办法做最简单的事情。
    从简单办法中找规律!

    day05
    程序 = 数据结构 + 算法
    良好的数据结构,可以极大提高程序的执行效率!

    数组:存储:连续存储多个数据的存储空间
    使用:相当于多个变量的集合
    why?现实中数据都是批量分类管理
    何时使用:只要批量管理多个数据,就要用数组保存
    如何使用:创建,初始化,访问数组中的数据
    创建:数组都是用[]创建出来的。
    var arr = [];——>创建了一个数组对象,数组中包含0个元素
    var arr = [90, 34, 23];——>创建了一个数组对象,数组中连续存储3个元素
    2个不限制:1、不限制元素的个数! 2、不限制元素数据类型

    *数组是引用类型的对象*
    原始类型:数据保存在变量本地
    引用类型:数据不保存在变量本地!保存在“堆”中。
    由地址指向实际数据
    引用类型特点:可以保存多个数据,而且数据个数随时变化
    why?原始类型中只能保存1个值
    1个值无法精确描述一个东西
    现实中,都是用多个属性共同描述一样东西
    对象:凡是存储在堆中的,都是对象!
    使用引用类型的对象:使用变量,等效使用对象的地址
    使用对象地址,等效于使用对象本身
    数组对象支持直接输出数组内容

    其他数组创建语法:var arr = new Array(num);
    new:要在堆中开辟空间!
    Array:ECMAScript标准的内置类型
    new Array:在堆中创建一个数组类型的存储区域
    (num):初始创建num个元素
    var arr = new Array(7);
    //[undefined, undefined, undefined, undefined, undefined, undefined, undefined]
    undefined输出时,变为一个空字符
    var arr = new Array(元素1, 元素2,..., 元素n);

    null:一个变量没有指向任何对象
    何时使用null:主动释放对象!主动释放的对象不能被找回
    null vs undefined:
    null专用于主动释放对象!
    undefined:专用于自动初始化任何未赋值的变量

    垃圾回收:js引擎自动销毁不再被引用的对象!
    垃圾回收程序:随js程序运行而后台同时运行
    只要对象还有变量引用,就不回收。

    访问数组:数组一组变量的集合。
    如何获得其中一个变量/数据:下标,数组中唯一标识一个元素的序号。从0开始。最后
    一个元素的下标是“元素个数-1”

    js内置对象不但封装存储,而且封装常用API
    API:已经实现的方法!可以直接调用!
    Array API:
    1、arr.length属性:数组中元素的个数
    访问任意数组的最后一个元素:arr[arr.length - 1]
    length属性值,随数组长度变化而自动变化!
    js中数组可根据程序需要,“自动扩容”,保证程序正常执行

    数组扩容和缩容:都是设置length属性的值
    如果length属性值>旧值,会扩容;反之,缩容(截断)
    被截断的元素,不能被找到,不会被回收。只能随数组对象一起回收。
    固定用法:在任意数组结尾追加一个新元素:arr[arr.length] = 新值;

    下午:
    栈中的变量 生命周期:和堆完全不同
    var a = 5;//全局变量随网页生命周期
    function fun(){
    var b = 10;
    }
    fun();//作用域环境栈
    /*fun的作用域环境栈 出栈 fun中局部变量,一同消失*/
    console.log(b);//refError
    结论:局部变量的声明周期和所在方法的作用域环境栈有关
    作用域创建,局部变量一同创建
    作用域结束,局部变量一同消失

    什么是数组遍历:对数组中每个元素执行相同的操作
    for(var i = 0; i < arr.length; i++){
    arr[i]——>当前元素
    }

    关联数组:数组下标可以自定义名称!Key/value对
    何时使用关联数组:数组元素的内容无法描述自己的意义时,使用关联数组为每个元素
    起名
    关联数组的length属性作废了!
    for in:专门遍历关联数组用的!
    for(var key in arr){
    //从第一个元素开始,将元素的key赋值给临时变量key
    arr[key]——>当前正在遍历的元素的值(value)
    }
    关联数组直接量定义方式:强调:大括号
    {"key1":"value1", "key2":"value2", ...}

    冒泡排序:[3, 5, 3,。。]:见array.html

    数组常用方法:
    x.toString()方法:任何对象都有toString方法
    默认用,分割每个元素
    将任何对象转为字符串
    一般不主动调用,js在需要时自动调用
    x.valueOf()方法:同toStrin()

    var str = arr.join("分隔符"):将数组转为字符串。但是可自定义分隔符!
    用法,将字符拼接为单词或句子 chars.join("");

    var newArr = arr.concat(1个元素值, [数组], ...):将参数拆散成单个元素,追加到数组
    中。
    *不会修改原数组,只能返回新数组对象*

    var subArr = arr.slice(start, end + 1);截取数组下标从start开始,到end位置的元素,
    生成子数组对象。*含头不含尾*

    arr.splice:删除!插入!替换!
    删除元素:arr.splice(start, count);
    替换元素:arr.splice(start, count, 值1, 值2, ...);
    插入元素:arr.splice(start, 0, 值1, 值2, ...)
    返回每次删除元素组成的新数组

    arr.reverse();颠倒所有数组元素
    arr.sort();默认升序排序。默认都转为字符串排序!

    day06
    手册:JavaScript——>js对象——>js数组——>Array对象参考手册
    回顾:
    转为字符串:x.toString()——>任何对象都有toString方法
    var str = arr.join("分隔符")——>自定义元素分隔符
    固定用法:arr.join("");——>将数组中的字符串无缝拼接为单词或字符串

    拼接和截取:var newArr = arr.concat(otherArr, 值1, ...)
    var subArr = arr.slice(start, end + 1);
    复制原始数组中的部分元素,原数组不变
    含头不含尾

    splice:*直接修改原数组!*返回被删除 的元素
    删除:[var removed =] arr.splice(start, count);
    替换:[var rrmoved =] arr.splice(start, count, 值1, 值2, ...);
    自动调整数组容量,容纳所有修改的新值
    插入:[var rrmoved =] arr.splice(start, 0, 值1, 值2, ...);

    正课:
    排序:arr.sort();默认按字符串升序排列
    自定义排序:2步:Step1:定义比较器函数!
    什么是比较器函数?定义任意两值比较策略的方法
    比如:num1 - num2 > 0 ——> num1 > num2
    num1 - num2 < 0 ——> num1 < num2
    function compare(a, b){
    return a - b;
    }//如果返回>0数,a > b; 如果返回<0数,a < b; 如果返回=0数,a = b;

    Step2:将比较器函数传递给sort方法!
    ***如何将方法做参数传递?***
    js中方法也是一个对象!方法名就是指向对象的变量名!
    function compare(a, b){return a - b;}
    //可以定义在使用前后的任何位置
    //原因:var声明和function声明自动提前!
    相当于:var compare = new Function("a", "b", "return a - b;");
    //必须定义在使用之前!原因:仅声明提前,赋值不能提前!
    arr.sort(compare);注意!将方法作为对象传递是,仅使用方法名,后不加圆
    括号。

    降序:颠倒比较结果,可以导致升序变降序
    升序:function compareASC(a, b){return a - b;}
    颠倒(*-1):function compareDESC(a, b){return b -a;}

    栈和队列:
    什么是栈?后进先出!(LIFO)栈其实就是数组,只不过用一对方法模拟了栈的操作!
    栈:只能从数组一端出栈,入栈。另外一端封闭!
    操作栈:
    结尾入栈出栈:元素下标始终不变,最后一个元素始终最新
    入栈:arr.push(值1, ...);
    出栈:var last = arr.pop();
    开头入栈出栈:所有元素下标随入栈出栈操作而变化
    入栈:arr.unshift(值1, ...);
    出栈:var first = arr.shift();
    队列:FIFFO
    入队列:arr.push(值1, ...);
    出队列:var first = arr.shift();

    二位数组:数组的元素又是另一个数组对象!
    创建二位数组:创建普通数组,完全一样!
    只不过将普通元素,换为一个数组对象而已
    var arr = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
    arr[3] = [10, 11, 12];
    如何访问二位数组中的任意元素:arr[父数组中的下标][子数组中的下标]
    何时使用二位数组:数据包含明显上下级关系

    内置对象
    什么是内置对象?内置对象就是ECMAScript标准中已经定义好的,由浏览器厂商已经
    实现的标准对象!
    内置对象中封装了专门的数据和操作数据常用的API。
    JavaScript中内置对象:
    String,Boolean,Number,Array,Date,Math,Error,Function,Object,Global

    包装类型
    什么是包装类型?专门封装原始类型的数据,并提供对数据常用操作的内置类型。
    为什么要用包装类型?让原始类型的数据也可以像引用类型一样,拥有方法和属性。
    JavaScript中的包装类型有三个:
    String类型,Number类型,Boolean类型
    何时使用包装类型?只要用原始类型的数据调用方法或访问属性,js引擎都会自动创建
    对应的包装类型对象。
    方法调用完,包装类型对象自动释放。
    var str = "Hello";
    //var strObject = new String(str);
    str += "world";
    //strObject = null;

    String包装类型:*字符串内容,一旦创建,不可改变*
    创建原始类型字符串变量:
    直接量:var stuName = "Smith";
    类型转换:var priceString = String(190.3);
    创建引用类型字符串对象:
    var carType = new String("BMW528Li");

    str.length:返回str字符串中的字符个数
    大小写转换:都转小写:str = str.toLowerCase();
    都转大写:str = str.toUpperCase();
    何时使用:希望大小写一视同仁时,就要先转换,在处理

    day07
    内置对象:见PPT
    包装类型:见PPT
    var num = 5.678;//原始类型
    //num = new Number(num);//包装类型
    console.log(num.toFixed(2));
    //num = null;//释放包装类型对象!

    创建字符串:原始类型还是包装类型?是否new
    var str = "...";//原始类型
    var str = String("...");//原始类型,类型转换
    **********************************************
    var strObj = new String("...");//包装类型对象

    转义字符:代替字符串中的非打印字符:
    如果字符串内容中包含和语法冲突的特殊字符,可用转为普通字符
    比如:console.log(" js是互联网"第一大语言"");

    字符串内容一旦创建不能改变!
    如果修改,都要创建新字符串,保存新结果,替换旧字符串
    var str = "Hello";
    var strObj = new String(str);
    str = str.toUpperCase();
    //strObj = null;
    console.log(str);
    *规律:所有字符串API,都需要变量接收返回值!*

    字符串的字符个数:str.length属性
    *字符串类型底层其实都是用字符数组实现的*
    比如:str[i]

    大小写转换:大小写字母一视同仁时,先转化,再处理
    比如:重名验证,重复邮箱,验证码

    获取指定位置的字符:var char = str.charAt(index);

    获取指定位置字符的unicode编码:var num = str.charCodeAt(index);

    优化:*频繁对字符串+=,要用数组代替!不会产生中间对象*
    Step1:每个字符串放入数组
    Step2:join("")拼接字符元素

    今天后要把任何类型变为String,不要用toString,而用+"",效率更高。

    字符串三大操作:1.查找关键字! 2.替换关键字 3.获取子字符串
    查找关键字:var index = str.indexOf("关键字");
    返回关键字所在位置!*如果没找到,返回-1!*
    indexOf:懒:只找第一个关键字位置!
    蠢:默认只能从位置0开始!
    var index = str.indexOf("关键字", from);
    from:开始查找的位置,从from开始向后查找
    一句话办几件事时,可以把表达式当值用!
    var str = "女神说要来,我草草的收拾了房间。结果她又说不来了。我说:我草";
    var index = -1;
    while((index = str.indexOf("我草", index + 1)) != -1){
    console.log("位置" + index + "发现关键字");
    }

    从最后一个字符,向前找:只要关键字离结尾近,就用last
    var index = str.lastIndexOf("关键字", from);
    from:开始查找的位置,从from开始向前查找
    *返回的index完全相同!字符在数组中的下标是固定的!*
    2处修改:index从str.length开始;每次index要-1

    2.获取子字符串:以下三个方法省略第二个参数,默认都是取到结尾!
    var subStr = str.slice(start, end + 1);
    start,end支持正负
    var subStr = str.substring(start, end + 1);
    用法同slice!唯一差别:不支持负值作为参数!
    var subStr = str.substr(start, *count*);
    JavaScript——>js字符串——>

    下午:
    按规律分割字符串:var subs = str.split("分隔符"[, count]);

    鄙视题:var str = "no zuo no die";

    课堂练习:判断字符的种类:unicode范围:
    48-57:0-9 数字字符
    65-90:A-Z 大写字母
    97-122: a-z 小写字母
    19968-40869:汉字

    什么是模式匹配:可以设置查找或替换的规则!
    何时使用模式匹配:要查找的关键字可能发生有规律的变化。
    如何使用模式匹配:1.先定义模式:/关键字/模式
    比如:var reg = /no/ig; no是要查找的关键字原文,不加""
    i表示忽略大小写! g表示全局查找和替换!

    String类型中,提供了专门支持模式匹配的API!
    按模式*替换*关键字:str = str.replace(reg, "新值");
    默认replace仅替换第一个关键字!
    要想全局替换,要在模式中定义“g”

    获得*所有*关键字的*内容:var kwords = str.match(reg);
    只能取得关键字的内容,无法确定每个关键字的位置!
    kwords.length:找到的关键字个数!
    *如果未找到,返回null!*
    只要有可能返回null!都要先判断 !=null,再处理!

    SetupRegexBuddy.exe 全部默认安装

    var index = str.search(reg); 和indexOf完全相同!
    indexOf不支持模式查找!search其实是indexOf的模式查找版

    今后在网页中只要处理字符串的格式,就要用正则表达式
    *正则表达式*
    什么是正则达表示:字符串中字符出现的规律
    何时使用正则表达式?验证字符串格式,查找关键字,替换关键字
    比如:银行卡查询密码:6位数字
    用户名:字母,数字,_的组合

    正则表达式:
    选择符号:[所有备选字符]:[去草],必须多选一使用
    一个[],只能代表一位字符的规则
    [^xxxx]:表示出了xxxx都行!反义。注意必须放在[]中的第一个位置,否则变为普通字
    符匹配。

    -符号:字符的范围:备选字符是连续的范围!
    比如:[0-9] [a-z] [A-Z] [a-zA-Z]//-可以局部使用
    汉字范围:[u4e00-u9fa5]

    预定义字符集:使用简化的符号,定义常用字符集
    比如:[0-9] ——> d [a-zA-Z0-9_] ——> w 空字符 ——> s

    如果规则正文中出现特殊符号,用转为原文

    .一个人一字符!

    数量词:规定前边一个字符出现次数的两次
    语法:{min,max}
    {num}:固定长度
    {min,}:至少min个,多了不限
    手机号:+86s1[3578]d{9}
    用户名:w{6,8}

    day08
    回复:
    []:备选字符集,只能多选一。一个[]只能匹配一位字符
    比如:我[去草]:我去 我草
    []内:开头^:除了xx都行:[01235689] ——> [^47]
    -:表示备选字符的范围 :[a-z] [0-9] [A-Z]

    预定义字符集:
    [0-9] ——> d
    [a-zA-Z_] ——> w
    s:空字符: 空格

    量词:修饰前一位字符出现的次数
    {min,max}:最少min个,最多max个
    {min,}:最少min个,最多不限制
    {num}:固定num个

    比如:验证座机号码:d{3,4}-d{7,8}

    正课:
    特殊数量词:+ * ?
    ?:可有可无,对多只能出现一次
    比如:我了?去: 我去 我了去 我了个去X 我了了去X

    *:可有可无,不限制出现次数
    比如:点亮我生命的火*:
    点亮我生命的
    点亮我生命的火
    点亮我生命的火火火

    +:至少出现一次!不限制出现次数
    比如:点亮我生命的火+:
    点亮我生命的火
    点亮我生命的火火火

    如果正文中出现+?*,都要用转义

    ():分组:改变模式的匹配顺序
    比如:验证身份证号:d{15}(d{2}[0-9xX])?
    验证手机号:(+86)?s+1[3578]d{9}

    ^:整个正则表达式的开头,表示以xxx开始
    $:整个正则表达式的结尾,表示以xxx结束

    ?= 预判,前一个字符之后,必须紧跟xxx
    ?! 预判,前一个字符之后,必须不能跟xxx

    课堂练习:中文姓名:[u4e00-u9fa5]{2,6}
    电子邮件:w+@w+([-]w+)*(.w+)+
    其中:w+([-]w+)* —— 匹配域名
    一个以上的字母,后可跟“-字母”,可有可无
    (.w+)+
    “.字母”组合至少出现1次

    RegExp对象:专门封装一条正则表达式,提供使用正则表达式的常用API
    如何使用RegExp对象:1.创建 2.调用API
    v如何创建正则表达式对象:ar regExp = /正则表达式/ig;
    API:
    验证:var boolean = regExp.test("被检查的字符串");
    如果验证通过:返回true;否则返回false
    验证 vs 查找:
    验证要求完整匹配!查找要求部分匹配!

    **test方法默认:只要找到就返回true!**
    正则表达式前加^,后加$

    查找:exec:查找关键字的位置,又能找到关键字的内容
    indexOf不支持正则,search支持正则,每次只能找1个
    match所有内容,但得不到位置!
    var arr = regExp.exec("被查找的内容");
    arr[0]:找到的关键字内容
    arr.index属性:找到的关键字的位置
    exec方法每次只能找1个,但是每次自动修改regExp对象的lastIndex属性!
    regExp对象的lastIndex属性:表示下次开始匹配的位置!

    查找:仅判断有没有,或者仅查找位置:str.indexOf()
    支持正则表达式:str.search()
    仅所有关键字的内容:str.match()
    即找位置,又找内容:regExp.exec()

    /正则表达式/
    var regExp = new RegExp("\d{6}", "ig"); 动态创建正则表达式
    强调:所有都要改为\

    贪婪模式: .+ .*,默认先匹配整个字符串,再缩小范围!
    懒惰模式: (.+?) (.*?),从第一个字符开始,向后扩展范围

    下午:
    从正则表达式匹配的内容中,取一部分:RegExp.$n
    n:正则表达式中第n个分组,其实就是第n个圆括号
    强调:分组从1开始
    必须通过RegExp类型,直接调用$n,不能使用对象!

    String对象与正则表达式
    str = str.replace(/正则表达式/ig, "替换值");
    var arr = str.match(/正则表达式/ig); str.search()
    str.split(/正则表达式/);

    trim功能:去除字符串开始和结尾的空格。中间空格不去除!
    对输入字符串的处理,多数要先清除开头结尾空格,再处理
    IE8不支持trim()方法!
    自定义trim()方法:
    function trim(str){
    var regExp = /(^s+)(s+$)/g;
    str = str.replace(regExp, "");
    return str;
    }

    String总结:所有的API都无法修改原字符串,都会返回新的字符串
    所有StringAPI都需要用变量保存结果!
    str.length 字符个数
    str = str.toUpperCase()/toLowerCase()
    查找关键字:var index = str.indexOf("关键字"[, from])
    var arr = str.match(/正则表达式/g);
    获得子字符串:var substr = str.slice(start, end + 1);
    str.substring(start, end + 1);
    str.substr(start, count);
    替换:str = str.replace(/正则表达式/g, "替换值");
    获得指定位置的字符:var char = str.charAt(index);
    str[index];
    字符编码转码:var code = str.charCodeAt(index);
    var char = String.fromCharCode(code);

    RegExp对象总结:
    var reg = /正则表达式/ig;
    var reg = new RegExp("正则表达式", "ig");
    *其中所有的都要改为\!*

    验证str中时候包含reg匹配的关键字:
    var boolean = reg.test(str);
    *强调:完整验证,都需要在正则表达式前加^后加$*

    同时查询所有关键字的内容和位置
    while((arr= reg.exec(str)) != null){
    arr[0] ——> 找到的一个关键
    arr.index ——> 当前关键字的位置
    }

    RegExp.$n:
    获得正则表达式中第n个分组(圆括号)匹配的子字符串

    Math类型:封装了所有数学计算有关的API
    不能new!
    Math.PI

    Math.round(num) ——> 四合五入取整
    Math.ceil(num) ——> 向上取整
    Math.floor(num) ——> 向下取整

    Math.pow(底数, 幂);
    Math.sqrt(num);//平方根!

    绝对值:Math.abs(num);

    Math.max/min(值1, 值2, 值3, ...);
    取数组中的最大值:var max = Math.max.apply(Math, arr);

    随机数:Math.random(); 0<=r<1
    任意min-max:
    Math.floor(Math.random() * (max - min +1) + min);

    /*随机生成四位验证码*/
    //Step1:数组:所有字母、数字
    var codes = [];
    for(var i = 48; i <= 57; codes.push(i), i++);
    for(var i = 65; i <= 90; codes.push(i), i++);
    for(var i = 97; i <= 122; codes.push(i), i++);

    function getCode(){
    var arr = [];
    for(var i = 0; i < 4; i++){//0-61之间取随机数
    var index = Math.floor(Math.random()*(60-0+1) + 0);
    var char = String.fromCharCode(codes[index]);
    arr.push(char);
    }
    return arr.join("");
    }

    while(true){
    var code = getCode();
    var input = prompt("输入验证码:" + code);
    var reg = /^[a-zA-Z0-9]{4}$/;
    if(reg.test(input)){
    if(code.toLowerCase() == input.toLowerCase()){
    document.write("登录成功");
    break;
    }else{
    alert("验证码输入错误!");
    }
    }
    }

    Date对象:封装一个时间点数据,提供对时间、日期的常用API
    创建:var date = new Date();
    1.创建Date类型对象; 2.自动获得浏览器当前时间点!
    自定义时间:var date = new Date("2015-6-9 16:47");
    1.创建Date类型对象; 2.自定义一个具体时间点

    *Date对象中,
    保存的是从1970年1月1日 0:00:00到现在的毫秒数
    var date = new Date();

    API:
    1.每个分量都有一对get/set方法,获取/设置该分量的值!
    2.命名:年/月/日 没有s,时,分,秒 有s
    3.取值、赋值:除了每月中的日之外,其余都是从0开始,到-1结束
    每月中的日,从1开始,带31结束
    月:取值时,要+1修正;赋值是,-1修正
    星期://日 一 ............ 六
    //0 1 6

    日期计算:两日期对象相减,得到毫秒数
    时间做+:var nowMs = date.getTime(); 返回时间毫秒数
    var nextMs = nowMs + 5*60*1000;
    var next = new Date(nextMs);
    使用毫秒做计算,不改变原时间对象!需要重新封装时间对象
    最大仅能算到“天数”。再算“月数”,无法确定每月天数。


    day09
    回顾:
    Date对象:内部封装了一个毫秒数
    创建日期对象:
    var date = new Date("2016/7/4");PPT上 new Date("2016-7-4");仅兼容chrome
    API
    1.每个分量都有一对get/set方法
    2.命名:年月日星期 不带s;时分秒带s
    3.值范围:月中的日:1-31;其他:0-减1

    计算:1.两日期相减,得到毫秒数
    2.日期+/- 天小时分秒:用毫秒
    3部:1.var ms = date.getTime();
    2.ms = ms +/- 毫秒数
    3.var newDate = new Date(ms);

    正课:
    3.任意分量的计算:
    先取出分量值,做计算,再set回去!

    var now = new Date();
    var day = now.getDate();//4
    day -= 10;//-6
    now.setDate(day);
    document.write(now);

    date.setXXX();1.自动调整进制
    2.*直接修改原日期对象*
    如何保留原日期对象?先new出新Date对象,再set
    var newDate = new Date(oldDate.getTime());

    日期格式转换:
    date.toLocaleString();//获得日期和时间的本地格式
    date.toLocaleDateString();//仅获得日期部分的本地格式
    date.toLocaleTimeString();//仅获得时间部分的本地格式

    日期格式转换:都要自定义format(date)方法!
    function format(date){
    var week = ["日", "一", "二", "三", "四", "五", "六"];
    var y = date.getFullYear() + "年";
    var m = date.getMonth() + 1 + "月";
    var d = date.getDate() + "日";

    var w = " 星期" + week[date.getDay()];

    var h = date.getHours();
    var am = h >= 12 ? " 上午 " : " 下午 ";
    h = h > 12 ? h - 12 : h;
    h = h < 10 ? "0" + h : "" + h;

    var mi = date.getMinutes();
    mi = mi < 10 ? "0" + mi : "" + mi;

    var s = date.getSeconds();
    s = s < 10 ? "0" + s : "" + s;

    var str = y + m + d + w + am + h + ":" + mi + ":" + s;
    return str;
    }

    Number类型 API:
    num.toFixed(n); 按n位小数四舍五入,*返回一个字符串*!
    何时使用:在计算之后,显示结果是,*最后调用toFixed方法*
    vs Math.round(num):只能取整 返回一个数Number

    num.toString(n):按n进制输出数字的字符串格式

    错误处理:
    什么是错误处理:导致程序运行停止的运行时异常状态
    什么是错误处理:在出现异常状态是,保证程序不停止的机制
    如何错误处理:
    错误类型:Error类型:所有错误对象的父类型
    6种子类型:EvalError,
    RangeError:参数超出范围
    比如:num.toFixed(n) n<0 抛出RangeError
    ReferenceError:引用错误:找不到对象
    比如:只要使用未声明的变量时,都要抛出ReferenceError
    SyntaxError:语法错误!修改源代码就可以解决!
    TypeError:错误的使用了类型和类型的方法!
    URIError:URI错误
    如何处理错误:
    try{
    可能出错的代码
    }catch(err){只要抛出错误,都要创建一个Error对象
    错误处理的代码
    1.获得错误信息:err.name 类型
    2.根据错误的类型,执行不同的处理
    }[finally{可有可无
    //程序中使用了大对象!一样要在finally中主动释放
    无论是否出错,都必须执行的代码
    }]

    能用if...else解决的问题,就不用try...catch!
    何时使用try...catch?try...catch处理的是无法预料的问题!

    主动抛出异常:如何告知方法调用者出错?
    thow new Error("自定义的错误信息");

    下午:
    Function对象:
    1.以声明方式定义方法:放前放后无所谓
    function 方法名(参数列表){方法体;return 返回值}
    2.以创建对象方式定义方法:必须定义在使用之前!
    var 方法名 = new Function("参数1", ..., "方法体;return 返回值");
    只有声明方式的方法定义才被提前解析!——方法声明提前

    重载:方法,根据传入的参数列表不同,执行不同的任务
    js支不支持重载:语法不支持,但是可以通过 arguments对象 模拟重载效果

    arguments对象:方法对象中保存所有参数的类数组对象
    类数组对象(object like array):长的像数组的对象
    *方法内,自动创建!直接使用!*
    arguments.length:保存变量的个数
    arguments[i]:访问传入的第i + 1个变量

    3.使用匿名函数赋值的方式定义方法:
    匿名函数:没有方法名的函数定义!
    var compare = function(a, b){return a-b;}

    鄙视题:js中方法定义的方式有几种:3种!
    A.function compare(a, b){return a - b}
    **************************************************************************
    B.var compare = function(a, b){return a - b;}
    C.var compare = new Function("a", "b", "return a- b;");
    D.var compare = new Function(a, b, return a- b;); X

    function isEmpty(str){
    if(str === undefined){
    return true;
    }else if(str == null){
    return true;
    }else{
    var reg = /^s*$/;
    return reg.test(str);
    }
    }

    var ltrim = function(str){
    var reg = /^s+/;
    return str.replace(reg, "");
    }
    var rtrim = function(str){
    var reg = /s+$/;
    return str.replace(reg, "");
    }

    匿名函数2个用途:
    1、回调函数:函数何时执行,程序员不需要控制!
    由所在环境执行!
    比较器!
    //var compare = function(a, b){return a - b;} arr.sort(compare);
    arr.sort(function(a, b){return a - b;})
    事件处理函数:onclick = "calc(12)";
    2、自调函数:匿名函数自己调用自己!
    当函数不需要重复使用时,使用匿名函数自调。
    语法:
    (function(参数...){
    方法体;
    })(参数值...);
    在函数定义的位置立即执行!

    闭包:函数外使用了不属于自己的局部变量
    何时使用闭包?保护局部变量

    day10
    回顾
    1. 闭包
    判断闭包3特点:
    1. 嵌套函数
    2. 内层函数操作了外层函数的局部变量
    3. 外层函数将内层函数返回到外部
    被全局变量保存住

    判断闭包执行结果:
    *1. 外层函数被调用几次,就有几个受保护的局部变量副本
    2. 反复调用来自一个闭包的函数,受保护的局部变量就变化几次

    正课:
    1. 面向对象
    1. 创建自定义对象
    2. ****继承

    1. 面向对象:在程序中都是用一个对象来描述现实中一个具体的东西;
    现实中的一个东西都包含属性和功能:
    属性:描述一个东西特点的变量
    功能:东西可以执行操作
    什么是对象:封装多个数据的存储空间
    什么是自定义对象:封装现实中一个东西的属性和功能的存储空
    间。现实中东西的属性会成为对象中的属性变量。现实中的东西的功能,会成为对象中
    的方法(函数)

    2. 创建自定义对象:3种方式:
    1. var obj = {'属性名1':值1,
    '属性名2':值2,
    ...
    '功能名1':function()
    {...}};
    js中一切都是对象!所有对象的底层都是hash数组

    属性:如何访问属性:2种:obj.属性名 obj["属性名"]
    访问对象中不存在的属性
    (访问数组中不存在的下标):不会出错,返回undefined
    强行给不存在属性赋值,不报错!js会自动创建同名属性

    如何判断某个对象是否包含指定成员:3种
    1. obj.hasOwnProperty("成员名");
    2. "属性名" in 对象
    如果找到,返回true,否则返回false
    3. 直接使用 obj.属性名 作为条件:
    arr.indexOf !== undefined
    如果不包含,返回undefined ————> false
    如果包含,返回值或function ————> true
    何时省略:判断方法是否存在时,可省略 !==
    如果确定属性值一定
    不是null, 0, "", NaN 也可省略

    方法:如何在方法中,访问当前对象自己:
    ****this关键字:运行时,指代正在*调用*方法的对象
    (.前的对象)
    this本质是window下唯一的一个指针,指向当前正在
    调用方法的对象

    如何在方法内,访问当前对象自己的属性:this.属性名
    **在方法内访问当前对象自己的属性,必须用this.属性

    省略this,默认访问活动对象和window中的变量(闭
    包除外)

    ***this和定义在哪无关!仅和调用时使用的当前对象有

    ***如果无主的调用或复制,默认this都是window!

    PM:
    正课:
    1. ***面向对象:继承
    面向对象三大特点:封装 继承 多态
    封装:将描述同一个东西的属性和方法,定义在一个对象中
    继承:父对象中的属性和方法,子对象可直接使用
    多态:同一个对象,在不同情况下,呈现不同的状态
    重载:同一方法名,传入参数不同,执行不同的操作
    重写:子对象觉得父对象的成员不好用,可自己定义一
    个,覆盖父对象的成员

    创建对象:3种:
    1. 对象直接量
    var obj = {"属性名":值, ..., "方法名":function(){...}};

    2. var obj = new Object();//创建一个空对象
    obj.属性名 = 值;
    obj.方法名 = function(){... this.属性名 ...};

    3. 利用构造函数*反复*创建*相同结构*的对象
    构造函数:描述一类对象结构的特殊函数
    2步:
    1. 定义构造函数
    function 构造函数名|类型名(属性参数1, ...){
    this.属性名 = 属性参数1;
    //在当前正在创建的对象中创建一个属性名
    //赋值为属性参数1的值
    ...
    this.方法名 = function(){
    ...this.属性名...
    }
    }
    2. 利用构造函数创建对象
    var obj = new 构造函数名|类型名(属性值1, ...);
    new:1. 创建一个空对象:new obj = {};
    2. 利用空对象,调用构造函数
    构造函数在空对象中添加属性和
    方法
    3. 设置新对象的 __proto__ 指向构造函数的
    prototype对象
    4. 返回新对象的地址

    继承:js中一切继承都是用原型对象实现的!
    原型对象:每个函数对象都有一个原型对象
    构造函数的原型对象负责保存所有子对象共享的成员!
    建议:所有子对象共享的方法,都应定义在构造函数的原型对象中。———
    —避免重复定义方法对象,浪费内存。
    说明:其实所有内置类型的API都是定义在类型.prototype

    扩展对象属性:2种扩展:
    1. 扩展共有属性:通过构造函数.prototype添加的属性
    2. 扩展自有属性:通过某一具体子对象添加属性
    判断自有属性或扩展属性:
    1. 判断自有属性:obj.hasOwnProperty("属性名");
    2. 判断共有属性:"属性名" in obj && !obj.hasOwnProperty("属性名")
    在原型对象关系中包含 且 子对
    象自己*没有*

    删除属性:delete 对象.属性名
    *仅能删除当前对象自己的属性,无法删除共有属性
    全局变量:3种
    var n = 1; window.n = 1; window["n"] = 1;
    不能delete 不能delete 能delete

    原型链:由各级对象的 __proto__ 逐级继承形成的关系
    获得任意对象的父级原型对象:Object.getPrototypeOf(子对象) =》子对象.__proto__
    检查对象的父对象:父对象.isPrototypeOf(子对象);


    day11
    面向对象:封装 继承 多态
    1. 创建对象:3种:4种:
    1. 直接量:var obj = {"属性名":值, ..., "方法名":function(){}};
    __proto__ ————> Object.prototype
    2. new关键字:var obj = new Object();
    obj.属性名 = 值;
    ...
    obj.方法名 = function(){}
    3. 使用构造函数反复创建相同结构的对象:2步
    1. 定义构造函数:
    function 构造函数名(属性参数, ...){
    this.属性名 = 属性参数;
    if(!构造函数名.prototype.方法名){
    构造函数名.prototype.方法名 =
    function(){}
    }
    }
    2. 使用new创建对象同时,调用构造函数:
    var obj = new 构造函数名(属性值, ...);
    4. Object.create(父对象, {扩展属性的列表对象});

    2. this:指代当前正在调用方法的对象
    this和定义在哪无关!仅和调用时使用的对象有关!
    所有无主(不用var赋值的变量,匿名函数)都是window的

    3. 原型,原型链,继承:
    原型:保存所有子对象共有属性和方法的对象!
    所有函数都有prototype,指向自己的原型对象
    所有对象都有 __proto__ ,指向自己父级原型对象
    所有原型对象都有constructor,指回原型对应的构造函数

    原型链:所有父子级对象间由 __proto__ 形成的多级引用关系
    ————>*多级*继承

    原型相关API:
    1. 判断自有属性和共有属性:
    1. 判断自有:obj.hasOwnProperty("属性名");
    2. 判断原型链上的属性:2种
    判断不包含:if(!("属性名" in obj/原型))
    if(obj.属性名 === undefined)
    if(!obj.属性名)
    3. 仅判断共有:必须满足两个条件
    !obj.hasOwnProperty("属性名") && obj.属性名
    2. 获得任意对象的原型:
    obj.__proto__ X
    Object.getPrototypeOf(obj)
    3. 判断父对象是否在子对象的原型链上
    父对象.isPrototypeOf(子对象)

    ***检测一个对象是不是数组类型:4种:
    1. Array.prototype.isPrototypeOf(obj);
    2. obj instanceof Array
    对象 是不是 构造函数 的实例
    3. obj.constructor == Array 仅判断直接父级
    4. 利用当前对象,强行调用原始的toString方法
    Object.prototype.toString.call(obj) == "[object Array]"
    apply(obj)
    继承:
    为什么要继承:代码重用!节省空间!
    1. 直接继承对象:想方设法修改对象的 __proto__ 属性
    3种:
    1. 仅修改一个对象的 __proto__
    Object.setPrototypeOf(子对象, 父对象);
    2. 通过修改构造函数的原型对象,实现批量修改后续子对象的继承关系。
    构造函数.prototype = 父对象
    强调:仅影响之后创建的对象的继承关系
    之前创建的对象依然继承旧构造函
    数.prototype
    3. var obj = Object.create(父对象[, {属性列表}])
    创建一个空对象,
    继承父对象中的属性,
    继承同时可再扩展属性和方法

    2. 仅继承结构:模拟java中的继承
    function 父类型构造函数(属性参数1, 属性参数2){
    this.属性1 = 属性参数1;
    this.属性2 = 属性参数2;
    }

    function 子类型构造函数(属性参数1, 属性参数2, 属性参数3){
    父类型构造函数.call(this, 属性参数1, 属性参数2);
    this.属性3 =属性参数3;
    }

    var obj = new 子类型构造函数(值1, 值2, 值3);

  • 相关阅读:
    SoapUI 使用笔记
    git 使用笔记(二)
    git 使用笔记(一)
    jquery 拓展
    hdu 1024 Max Sum Plus Plus (DP)
    hdu 2602 Bone Collector (01背包)
    hdu 1688 Sightseeing (最短路径)
    hdu 3191 How Many Paths Are There (次短路径数)
    hdu 2722 Here We Go(relians) Again (最短路径)
    hdu 1596 find the safest road (最短路径)
  • 原文地址:https://www.cnblogs.com/skorzeny/p/5668527.html
Copyright © 2011-2022 走看看