JS学习心得

218 阅读5分钟

js概述

 HTML+CSS+JavaScript并称前端三件套分别有着不同的功能,HTML负责的是网页的结构,css负责网页的样式,js负责网页的动态交互;
   js分为ECMAScript - 核心语法,以后JS不管做什么操作可能都离不开它(算法题/逻辑题)
         DOM	    - Document Object Model - 文档对象模型,可以用JS来操作HTML和CSS了
	 BOM 	    - Browser Object Model - 浏览器对象模型,可以用来操作浏览器
 一、js是一门弱类型、解释型、面向对象的脚本语言
    1.弱类型:变量保存的数据是可以随意的,数据类型是由数据来决定的。----要求比较自由
      强类型:变量保存的数据,是由数据类型来决定的。---要求比较严格
    2.解释型:在运行程序之前,不需要先检查语法是否正则,直接执行,但是碰到错误就会停止后续代码。
      编译型:在运行程序之前,需要先检查语法是否正则,如果不正确,直接不允许运行。
    3.面向对象:编程中,万物皆对象。
 二、js的两种使用方法
    1.直接在HTML的script标签中写js代码。
    2.通过script标签的src属性,外部引入js代码。(该script标签不能再写其他代码)
 三、如何检查js代码
    1.通常使用console.log()输出在控制台并分析代码的错误。
    2.使使用document.write()输出在页面上查看并分析代码的错误。
    3.在弹出框输出日志:alert()输出在BOM上的警告弹出框中查看输出的代码。

js基本数据

js数据类型:

  • 值/基本数据类型:数字(Number)、字符串(String)、布尔类型(Boolean)、undefinednullSymbol
  • 引用数据类型/对象类型:对象(Object)、数组(Array)、函数(Function),还有两个特殊的对象:正则(RegExp)和日期(Date

数据类型的转换

一、数据的隐式转换

算数运算符具有隐式转换功能

“+”运算

  •  把“+”两边转换成数字类型进行运算。
    
  •  碰见字符串“+”运算变成拼接操作。
    
  •  碰见boolean类型 true>>>1,false>>>0。 碰见undefined>>>NaN。碰见null>>>0

“*/%”运算

  • 字符串也可以转为一个数字,前提要是一个纯数字组成的字符串才行,但凡包含一个非数字字符就转为NaN
  • NaN:Not A Number:不是一个数字,但却是数字类型
  1. NaN参与任何算术运算结果都是NaN
    
  2. NaN参与任何比较运算结果都是false(和自己比较也是false

二、强制类型转换

  1. 转字符串:var str=x.toString();---x不能是undefinednull,因为undefinednull不能使用任何的.操作页面上的一切东西,数据类型默认都是一个字符串。
    
  2. 转数字:	
    
  •  parseInt(str/num);       parse->解析  Int->整型
    
  •  parseFloat(str);		parse->解析  Float->浮点型
    
  •  Number(x);               (不好用)此方法可使任何类型转为数字,但是完全等效于隐式转化
    

function函数基础

  1. Function:函数,称之为方法:需要提前【预定义好】的,以后就可以【反复使用】的【代码段】。
    
  2. 如何使用:
     1、先定义/声明/创建函数:
     	function 函数名(){
     		若干的代码
     	}
     2、再调用/使用函数:
     	1、要么在js中程序员直接写死,要执行几次:函数名();
     	2、交给用户绑定在某个元素上,写上点击事件,让用户来触发。
     		<elem onclick="js代码">内容</elem>
    
  3.  带参数的函数:创建:形参:形式参数,其实就是一个变量,但是不需要写var,而且默认也没有保存任何值,默认值为undefined
     	function 函数名(形参,形参,...){
     		函数体;
     	}
     使用:实参:实际参数,真正的值,需要再你调用时再传入
     	函数名(实参,实参,...)
     特殊:1、传实参的顺序一定要和形参的顺序一一对应,并且数量也要对应
           2、不是一定要带参数的函数才是好函数,具体情况,需要具体分析:
                         如果你的函数体就是固定的 - 则普通函数
                         如果你的函数体希望根据传入的实参不同,做的略微不同 - 则带有参数的函数
    

分支结构

  1. 程序的流程控制语句:3种
         1、顺序执行 - 默认,从上向下的依次执行
         2、分支结构 - 通过条件的判断,选择部分代码执行
         3、循环结构 - 通过条件的判断,选择要不要重复执行某些代码
    
  2. 比较运算符:>、 <、 >=、 <=、 ==、 !=
     用于做判断/比较的
     结果:一定是一个布尔值
     强调:如果你想要判断多个条件,绝对不能像小时候数学的写法:18<=age<=65,错误的!
     	解决:逻辑运算符
    
  3. 逻辑运算符:
     &&:与,并且:要求全部条件都要满足,最后的结果才为true
     	           只要有一个条件不满足,结果则为false
    
     ||:或:要求全部条件都要不满足,最后的结果才为false
                只要有一个条件满足,结果则为true
    
     !:颠倒布尔值
    
  4. 分支的语法:
     一个条件,一件事,满足就做,不满足就不做
     	if(条件){
     		操作
     	}
    
     一个条件,两件事,满足就做第一件,不满足就做第二件
     	if(条件){
     		操作
     	}else{
     		默认操作
     	}
    
     多个条件,多件事,满足谁就做谁
     	if(条件1){
     		操作1
     	}else if(条件2){
     		操作2
     	}else{
     		默认操作
     	}
    

循环结构

循环结构:反复执行【相同或相似】的操作

  1. 循环三要素:
     1、循环条件:开始 - 结束,循环的次数
     2、循环体:做的操作是什么
     3、循环变量:记录着我们当前在哪一次,而且他会不断的变化,往往都会向着不满足循环条件进行
    
  2.  while循环:
                 语法:
                 var 循环变量=几;
                 while(循环条件){
                         循环体;
                         循环变量变化;
     特殊:有的时候真可能不知道从何开始,到何处结束,
           死循环:永远不会停下来的循环
           何时使用:不确定循环次数的时候
                 while(true){
     		循环体;
     	}
     退出循环语句:break - 只能在循环中使用,多半都是搭配死循环使用的
    

数组的基础

数组:创建一个变量可以保存【多个数据】的集合
	数组都是线性排列,除了第一个元素,每个元素都有唯一的前驱元素
			除了最后一个元素,每个元素都有唯一的后继元素
	每个元素都有一个自己的位置,称之为叫做下标,下标是从0开始的,到最大长度-1
  1. 创建数组:2种
    1、直接量方式:
    	var arr=[];//空数组
    	var arr=[数据1,....];
    
    2、构造函数方式:
    	var arr=new Array();//空数组
    	var arr=new Array(数据1,....);//而且这个方法还有一个坑
    
  2. 获取数组中的数据
         数组名[下标];
    
  3. 添加/替换
     数组名[下标]=新值;
     下标处有没有元素,如果没有则为添加,如果有了就为替换
    
  4.  数组具有三大不限制
     1、不限制元素的个数
     2、不限制元素的类型
     3、不限制元素的下标越界 - 会得到undefined,这是编程中不想看到的
        如果获取元素,下标越界,返回的一个undefined
        如果添加元素,下标越界,会得到一个稀疏数组,导致下标不再连续,如果搭配上循环去遍历每一个元素的话,我们会得到很多很多的undefined
    
  5. 解决:数组中唯一的属性:长度:数组名.length - 获取当前数组的长度:最大下标+1
     三个固定套路:
     	1、获取倒数第n个元素:arr[arr.length-n]
     	2、始终向末尾添加元素:arr[arr.length]=新值;
     	3、缩容:删除倒数n个元素:arr.length-=n
     前面的下标好数,后面的下标也好数,但是中间的下标还是不好数
    
  6. 往往很多情况,我们不会拿出某个元素来使用,而是拿出所有的每个元素来进行 相同 或 相似的操作
     遍历数组:把数组中的每个元素拿出来执行相同相似的操作
     公式:
     	for(var i=0;i<数组名.length;i++){
     		console.log(数组名[i]);
     	}
    

DOM

  1.  Document Object Model:文档对象模型:专门用于操作HTML文档的,提供了一些属性和方法等待我们学习
    
  2.  DOM树概念:DOM将我们的HTML看做了是一个倒挂的树状结构,但是树根不是html标签,而是document对象
     document对象:不需要我程序员创建的,由浏览器的js解释器自动创建,一个页面只有一个document
     作用:可以通过树根找到我们想要的任何一个DOM元素/节点/对象(属性和方法)
     DOM会将页面上每个元素、属性、文本、注释都会当作一个DOM元素/节点/对象
    
  3.  查找元素:
         一、通过ID查找元素
     语法:var elem=document.getElementById("id值");
     特殊:
     	1、返回值,找到了返回的是一个当前找到的DOM元素,没找到,返回一个null,做了别的操作可能就会报错了
     	2、找到了多个相同的id,那么只会返回第一个
     	3、一次只能获取一个元素,也只能操作一个元素,麻烦
     	4、其实根本不需要使用此方法,直接写ID也可以找到元素
    
         二、通过标签名查找元素
     语法:var elems=document/已经找到了的父元素.getElementsByTagName("标签名");
     特殊:
     	1、返回值:找到了返回的一个是类数组DOM集合(很像数组,都能用下标,都能用length,都能遍历),没找到返回一个空集合
     	2、JS不能直接操作DOM集合,只能直接操作DOM元素,解决:要么使用下标拿到某一个元素,要么使用遍历拿到每一个元素
     	3、不一定非要从document开始查找,如果document去找,会找到所有的元素,可以换成我们已经找到的某个父元素,就只会找到这个父元素下面的元素了
    
         三、通过class名查找元素
     语法:var elems=document/已经找到了的父元素.getElementsByClassName("标签名");
     特殊:
     	1、返回值:找到了返回的一个是类数组DOM集合(很像数组,都能用下标,都能用length,都能遍历),没找到返回一个空集合
     	2、JS不能直接操作DOM集合,只能直接操作DOM元素,解决:要么使用下标拿到某一个元素,要么使用遍历拿到每一个元素
     	3、不一定非要从document开始查找,如果document去找,会找到所有的元素,可以换成我们已经找到的某个父元素,就只会找到这个父元素下面的元素了
    
         四、通过关系查找元素:前提条件:必须先找到一个元素才可以调用关系网
                 父元素:elem.parentNode; 
                 子元素:elem.children; - 集合
                 第一个儿子:elem.firstElementChild;
                 最后一个儿子:elem.lastElementChild;
                 前一个兄弟:elem.previousElementSibling;
                 后一个兄弟:elem.nextElementSibling;
           强调:DOM集合不能直接做操作!
    

操作元素:

    前提:找到元素才能操作元素:<标签 属性名="属性值" style="样式">内容</标签>
1、*内容:
	1、*innerHTML:获取 和 设置 开始标签到结束标签之间的内容 - 支持识别标签
		获取:elem.innerHTML;
		设置:elem.innerHTML="新内容";

	2、innerText:获取 和 设置 开始标签到结束标签之间的文本 - 不支持识别标签
		获取:elem.innerText;
		设置:elem.innerText="新文本";

	以上两个属性都是为双标签准备的,但是操作不了单标签input的内容

	3、*value:专门为input的value值准备的
		获取:input.value;
		设置:input.value="新值";

2、属性:
	获取属性值:elem.getAttribute("属性名");
	设置属性值:elem.setAttribute("属性名","属性值");
    可简化为:
	获取属性值:elem.属性名;
	设置属性值:elem.属性名="新属性值";
	缺陷:
		1、class必须写为className - 2015年过后,ES6诞生过后,class变成了一个关键字
		2、不能操作自定义属性,只能操作标准属性
3、样式
	使用样式的方式:
		1、*内联/行内样式
		2、内部样式表
		3、外部样式表
	获取:elem.style.css属性名;
	设置:elem.style.css属性名="css属性值";
	特殊:
		1、css属性名,有横线的地方,去掉横线,线后第一个字母大写
			例:border-radius   ->	borderRadius
		2、获取时,只能获取内联样式 
4、绑定事件:
	elem.on事件名=function(){
                        操作;
                    }
		*****this关键字:目前只能用于事件内:
			如果单个元素绑定事件:this->这个元素
			如果多个元素绑定事件:this->当前触发事件的元素
   5、eval()方法
       *函数*功能 :eval()通常用来执行一个字符串表达式,并返回表达式的值。