js的基础

219 阅读13分钟

Javascript

概念:简称js,是一个运行在[在客户端浏览器端]的[解释型][弱类型][面向对象]脚本语言

js的运行环境

 浏览器自带js解释器,不需要安装任何环境
 等到我们学习Node.js的时候,确实需要自己安装一个服务器端的环境

编译型:

在程序执行之前,需要先检查语法是否正确。如果不正确,直接不运行,比如:Java、c++...严格

解释型:

在程序执行之前,不需要先检查语法是否正确,直接运行。碰到错误后就会停止后续代码,比如:js、php...更加自由

弱类型:

变量保存的数据可以随意,数据的类型由数据决定----更加自由

1 - Number 数字 "1" - String 字符串

强类型:

变量保存的数据,由数据的类型来决定了能保存什么数据 - 比如:Java-----更严格

面对对象

以后经常遇到的写法,这种写法就是面对对象 对象名.属性名 对象名.方法名() 在js中万物皆为对象,除了某两个人

特点:

可以用一切编辑工具编写js代码,编辑器不代表你的实力
解释型
弱类型
面向对象
可以做一切css完成不了的效果(轮播、选项卡、购物车...)
和服务器进行连接,进行沟通

如何使用js:

  使用方式:
    1、 直接在HTML上写一个script标签,在里面书写js代码--<script>js的代码</script>
    2、创建一个xx.js文件,在其中写入js代码,最后在HTML引入一正式开发使用方式--<script src="js的路径">此处不写代码</script>
  
  
  输出方式/打桩输出/检查错误:
  1、在控制台打印输出日志,console.log(你想要输出的东西);//console 控制台 log 日志
  2、在页面上输出日志:document.write(你想要输出的东西);//document 文档(当前的HTML文档) write 写入.支持标签,但有一个缺点:平时使用无所谓,但如果绑定了一个点击事件,会将页面所有的内容去全部替换掉,导致网页白写。
  3、在浏览器自带的警告框输出日志:alert(你想要输出大的东西);//alert 警告 会卡住网页,用户只能看到一个白板。

变量和常量

三个w:what when who 一个h:how

变量:创建后,值可以再次修改

何时使用:以后反复使用到的数据,都要先提前把他保存在一个变量中,以后反复使用变量名相当于就是在使用变量的值。

为什么:为了方便。

如何使用:var 变量名=值.

     特殊:
        变量名其实不是随意的
        1、不能以数字开头
        2、建议使用驼峰命名法或者下划线命名法
        3、命名要尽量的见名知意
        如果你的变量名是name,不管你保存的数据类型是什么,都会转为一个字符串.name这个变量名是一个关键字。
        变量名不能是关键字
        变量可以只创建,不赋值,默认值为undefined,但不使用
        如果多个变量连续创建,简写:
        var name="xx",
            age = xx ,
            gender="x",
            hobby="xx"

常量:创建后,值不允许再次修改 语法:const 常量名=值

       数据类型分为两大类
       1、原始/基本类型
          1、Number - 数字 取值有无数个,直接写数字,不加任何东西。(控制台输出颜色为蓝色)
          2、String - 字符串   取值有无数个,必须加上""或者''.(控制台输出颜色为黑色)
          3、Boolean - 布尔    取值只有2个,分别是true(真|对)或者false(假|错),一般用于当作条件判断,需要搭配上分支结构(控制台输出颜色为蓝色)
          4、Null - 空 取值只有一个 null .作用是用于释放变量,释放内存的,节约内存空间,但是有更好的方法。(控制台输出颜色为灰色)
          5、Undefined - 未定义 取值为undefined,变量默认值为undefined。
      
      查看数据类型:typeof(变量)
      
      2、引用/对象类型:11

运算符

   1、算术运算符:+ - * / %
      特殊:
      1、%:取余,俗称模,两个数相除,不取商而是取除不尽的余数
         作用:
         1、任意数%2 - 判断奇偶数
         2、取出某个数字的后n位
         console.log(1234%10);//4
         console.log(1234%100);//34
         console.log(1234%1000);///234
      2、带有隐式转换;会将数据类型转换,发生变化;默认将左右两边转为数字,再运算
         true -> 1
         false -> 0
         undefined -> NaN
         null -> 0
         "100" -> 100
         "100px" -> NaN  确实可以将字符串转为数字,但必须是纯数字组成的字符串才行,凡包含了非数字字符,则为NaN
         NaN:Not a Number;不是一个数字,但是他确实是数字类型,不是一个有效数字,没有任何优点,但有两个缺点:1、参与任何算术运算结果认为NaN
             2、参与任何比较运算结果都为false
      +运算符:如果碰上一个字符串,左右两边都会转为字符串,+运算不要再是+运算,而是拼接工作
   
   2、关系/比较运算符:> < >= <= == === != !==
   何时使用:一般出现在分支结构中,通过条件判断满足不满足,走不同的路线
   结果:一定是一个布尔值
   带有隐式转换:默认左右两边都会转为数字再比较大小
   特殊:
      1、如果参与比较的两边[都是]一个字符串,则会按位pk,每个字符的十六进制unicode号(十进制ASCII码)  
      数字0-9<大写A-Z<小写a-z<汉字
      常识:汉字第一个字:一 unicode号:4e00 ascii码:19968
            汉字最后一个字:龥 unicode号:9fa2 ascii码:40869
      2NaN参与比较运算结果都为false
      判断一个x是不是NaN
      !isNaN(X) 结果一定是一个布尔值:
      true -> 是一个有效数字
      false -> 是一个NaN
      3undefined==null;//true
      解决:===全等:不带隐式转换的值等值比较,要求数据相同,值也相同
      
   3、逻辑运算符:在比较运算的基础上,再进行综合比较,一个条件比较不出来,可以考虑综合比较
      &&:与(并且)
      全部条件满足,结果才为true,只要一个条件不满足,结果为false
      ||或者
      全部条件不满足才为false,只要满足一个,结果为true
      !颠倒布尔值
      !true -> false
      !false -> true
   
   4、赋值运算符:= += -= *= /= %=
      1、赋值符号为 =,将=右边的东西保存到=左边的变量名中
      2、后5个可以理解为是一种升级写法,一句话两个操作,运算后再保存回变量本身
      i=i+1==>i+=1
      
   5、自增自减运算符:++ --
   举例:i++===i+=1===i=i+1
   自增:固定的每次只能+1
   累加:+=每次加几由程序员自己决定
   
       前++和后++的区别
         1、如果独自使用,前++和后++没有任何区别
         2、如果参与了其他表达式,变量始终都会+1,但前++和后++[返回的结果]不同
         前++返回的是加了之后的新值
         后++返回的是加了之前的旧值
   
   6、位运算
      左移:m<<n,读作m左移了n位,翻译:m*2的n次方
      右移:m>>n,读作m右移了n位,翻译:m/2的n次方
      
   扩展:用户输入框:var user=pyompt("提示文字""默认值")  
   

分支结构

     程序的流程控制语句:
     1、顺序结构 - 默认值:从上向下依次执行每句话
     2、分支结构 - 通过条件判断,选择部分代码执行
     3、循环结构 - 通过条件判断,要不要反复执行某代码
     如何使用:
     1if分支:
        1、一个条件,一件事,满足就做,不满足就不做
          if(条件){
                  操作;              
          }
        2、一个条件,两件事,满足就做第一件,不满足就做第二件
          if(条件){
                操作;
          }else{
              默认操作;
          }
        3、多个条件,多件事,满足谁就做谁
         if(条件){
              操作;
         }else if(条件2){
              操作;
         }else if(条件3){
              操作;
         }else{
              默认操作;
         }
    注意: 1.分支只要满足了一条路。就不会再走别的路,书写顺序很重要
          2.else if想写多少句,由程序员决定
          3.else 可以省略不写,但不推荐,如果条件不满足,则都不执行
          4.分支结构可以嵌套
          
    2switch...case分支  前提:只有知道最后的结果是什么,才能用
    语法:
         switch(变量/表达式){
         case1:
         操作 1break;
         case2:
         操作 2breakcase3:
         操作 3breakdefault:
         默认操作;
         }
   注意:1.case的比较不带隐式转换
        2.问题:默认只要一个case满足以后,会把续所有操作做完
          解决:每个case的操作后跟上一个break,最后一个default可以省略break,如果多个条件做法是一样的,可以省略中间部分
        3.default 可以省略,但不推荐
        ifswitch 的区别
          1.switch...case 优点:执行效率高,速度比较快(比较时,case做的不是范围查找而是等值比较,且不带隐式转换)缺点:不能做范围查找
          2.if...else 优点:可以做范围比较   缺点:执行效率低,速度比较慢
      建议:代码开发完毕后,要多做代码优化,尽量少用if...else,将其替换成switch...case
      
  3、三目运算:纯粹为了简化[简单的]分支;操作只能有一句话
  语法:
     短路逻辑:条件&&(操作)         ===if
     
     条件?操作1:默认操作;          ===if...else
     
     条件1?操作1:条件2?操作2;默认操作;     ===if...else if...else
 注意:1.默认操作是不能省略的,省略会报错 - 其实算优点
     2.如果操作比较复杂,不能使用三目运算
  

强制(显示)数据类型转换

  1.转字符串
    1.var str=x.toString();//x不能时undefined和null     undefined和null不能使用.去做任何操作
    2.var str=String(x); 万能的,任何人都可以转为字符串,完全等效于隐式转换,其中String()就是隐式转换的底层逻辑,还不如+" "
    页面上的一切都是字符串
  
  2.转数字
    1.*parseInt(ste/num) - parse解析 Int整型 用于将[字符串转为整数]的
      执行原理:从左向右依次读取每个字符,碰到非数字字符就会停止转换,开始就不认识则为NaN,不认识小数点
      console.log(parseInt(35.5));//35
      console.log(parseInt(3hello5));//3
      console.log(parseInt(true));//NaN
    2.*parseFloat(str) - parse解析 Float浮点型(小数),用于将[字符串转为小数]的
      执行原理:几乎和parseInt一致,认识第一个小数点
      console.log(parseFloat(35.5));//35.5
      console.log(parseFloat(35.5.5);//35.5
 
 3、转布尔
      Boolean(x)//万能的,任何人都可以转为字符串,完全等效于隐式转换,其中String()就是隐式转换的底层逻辑,还不如!!x
      只有6个会为false0undefinednull,"",false,NaN,
      其余都为true

循环结构

  反复执行相同或相似的操作

循环三要素:
    1、循环条件:开始 -- 结束,循环的次数
    2、循环体 每次循环要做什么操作
    3、循环变量:记录当前在哪一次,而且会不断的变化,变化往往时想着不满足循环条件前进
    
循环结构:
1.while 循环:
语法:
var 循环变量=几;
while(循环条件){
    循环体;
    循环变量变化起来;
    }
特殊:
   1.有的时候可能需要使用死循环,默认永远不会停止的循环
   何时:不确定循环次数的时候
   while(true){
      死循环操作;
   }
死循环其实也会停下
 break - 退出整个循环,多半是搭配死循环使用的
 continue - 退出本次循环,下一次还是会执行
 

随机整数的公式: var r=parseInt(Math.rondom()*(max-min+1)+min)

2for循环:和while原理一致上去比while更加简洁,while能做的,for也能做
语法:
    for(var 循环变量=几;循环条件;循环变量变化起来){
      循环体;
      }
      whilefor 的区别:whilefor,从原理上没区别
      while更麻烦,不确定循环次数时使用-死循环
      for更简单,确定循环次数时用,大多数用它
      
3do...while循环:不使用
语法:
   var 循环变量=几;
 do{
    循环体;
    循环变量变化起来;
    }while(循环条件)
    
 do...whilewhile 的区别
 区别只看第一次,第一次满足条件,两者没区别
 第一次不满足条件,while一次都不会执行,do...while至少执行一次
 

Function 基础

概念:Function - 函数,也称为方法,先预定义,以后就可以[反复使用]的代码段
如何使用
定义/创建声明:
function 函数名(){
      函数体/代码段;
      }
调用函数
     1.直接在js内部书写:函数名()   程序员书写几次就调用几次
     2.在html页面上绑定点击事件
     <elem onclick="函数名()">文字</elem>   用户点击几次就调用几次
何时使用函数
      1.不希望打开页面立刻执行
      2.希望由用户来触发,提升用户体验感
      3.以后每一个独立的功能都要封装为一个函数
      4.函数地位很高,js中的第一等公民

带参数的函数
     1.创建出带有形参的函数,就是一个变量,不需要写var,而且不赋值,称为形式函数,简称形参
     function 函数名(形参,...){
            函数体;
            }
     2.使用带参数的函数时,必须传入实参 - 实际参数
     function 函数名(实参,...){
            函数体;
            }
注意:传参的时候顺序必须和形参顺序一一对应上数量也不能多不能少

总结:
    1.不带参数的函数用于执行一些固定的操作
    2.带参的函数,根据传入的实参不同执行的操作可以略微不同
    
循环和函数的区别    时机不同
    循环:几乎是打开页面一瞬间完成
    函数:需要调用才能执行
    
自定义函数
    创建:
    1.[声明方式]创建函数
     function 函数名(形参){
          函数体;
          return  返回值;
      }
    2.[直接量方式]创建函数
    var 函数名=function(形参){
         函数体;
         return  返回值;
      }
函数名尽量不重复,否则会覆盖前面的

 调用函数   
    var result=函数名(实参)
    
作用域
1.全局作用域:全局变量和全局函数 在页面任何位置都能使用/访问
2.局部/函数作用域:局部变量和局部函数,只能在[函数调用时,内部使用]

带来变量的使用规则:优先使用局部的,局部没有找全局,全局没有就报错
 特殊点/缺点:
 1.局部可以使用全局,全局不能使用局部的  解决:加return
 2.千万不要在函数中对未声明的变脸(如a=1)赋值,会全局污染,降低性能
 
声明提前   (只会在笔试题里)
   原理:在程序正式执行之前,会将var声明的变量(轻)和function声明的函数(),集中提前到当前作用域,赋值留在原地
   
重载
   在相同的函数名,根据传入的实参的不同,自动选择对应的函数取执行,但是js不支持
   在[函数内部]自带一个arguments对象(类数组对象),不需要我们创建

固定套路:
    arguments[i]   i下标从零开始
    arguments.length   通过函数内部分支判断arguments不同,执行不同的操作
    
    

数组的基础

  数组:创建有一个变量可以保存多个数据
  每个元素都有一个自己的位置,称为下标,下标是从0开始,到最大长度-1
  
  创建数组
    var arr=[数据1,...]      直接量方式
    var arr=new Array(数据1,...)    构造函数方式
    获取数组中的数据
      数组名[i]
      
  后续添加/替换元素
  数据名[i]=新数据   如果下标没有就是添加;下标有人就是替换
  
  数组三大不限制
   1.不限制元素类型
   2.不限制元素个数
   3.不限制下标越界
   
   数组唯一属性:length
   
   固定套路
   1.获得数组倒数第几个元素     arr[arr.length-n]
   2.向末尾添加元素:arr[arr.length]=新元素
   3.缩容:删除数组倒数N个元素   arr.length-=n
   
   遍历数组
    公式:
    for(var i=0;i<arr.length;i++){
       arr[i];//当前次元素
       }

DOM Document Object Model

   文档对象模型,专门用来操作HTML文档的
   
  查找元素
  1.通过ID查找元素: var elem=document.getElementByid("id")
  
  2.通过标签名查找元素: var elem=document.getElementByTagName("标签名")
  
  3.通过class名查找元素: var elem=document.getElementByClassNanme("class名")
  
  4.通过关系找元素:
  父亲:elem.parentNode;//单个元素
  儿子:elem.children;//集合
  第一个儿子:elem.firstElementChild;//单个元素
  最后一个儿子:elem.lastElementChild;//单个元素
  前一个兄弟:elem.previousElementSibing;//单个元素
  后一个兄弟:elem.nextElementSibing;//单个元素
  
  操作元素:前提要先找到元素
  内容:
  1.innerHTML [支持识别标签]
  获取:elem.innerHTML;
  设置:elem.innerHTML="新内容";
  
  2.innerText  [不支持识别标签]
  获取:elem.innertext;
  设置:elem.innertext="新内容";
  
  3.value 用于input
  获取:input.value;
  设置:input.value="新内容";
  
  属性
  获取属性值: elem.getAttribute("属性名")
  设置属性值: elem.setAttribute("属性名","属性值")
  简化:
  获取: elem.属性名
  设置: elem.属性名="属性值"
  简化缺陷:
  class 必须写为className.
  只能操作标准属性,不能操作自定义属性
  
  样式
  使用样式的方式
  1.内联样式
  2.内部样式表
  3.外部样式表
  
  用js操作[内联样式]
  1.不会牵一发而动全身
  2.优先级最高
  获取: elem.style.属性名
  设置: elem.style.css属性名="css属性值"
  特殊点
  border-radius - borderRadius
  获取时只能获取内联样式
  
  绑定事件
  elem.onclick=funcition(){
  操作;
  关键字:this 只能用于事件内部
  单个元素绑定事件:this ->这个元素
  多个元素绑定事件:this ->当前触发元素
  }
  一切获取,都为了判断
  一切设置,都是修改