JS(一)基本知识

一 JS的导入以及常用的输出方式

1、导入方式

(1)行内导入JS(不推荐使用)
<body>
    <div onclick="alert('hello')">HELLO WORLD</div>  /*当点击HELLO WORLD文字时,会弹出弹窗,显示hello*/
</body>
</html>
捕获.PNG

注意:慎重使用行内导入JS,因为不安全,所以不建议使用行内导入JS。

(2)内嵌式导入JS
<script type="text/javascript">
        alert('hello')    /*弹窗自动弹出hello*/
    </script>
(3)外链式导入JS
<script src="1.js">  </script> /*从外部文件链入*/

注意:内嵌导入和外链导入不能合并在一起,如果当前是外链导入的,那么在<script>脚本块中编写的所有代码都不会被执行。

2、

  • 真实项目中,我们一般都会把CSS放在<body>的上面,把JS放在<body>的末尾(约定俗成的规范)
  • <body>中编写的都是HTML标签,JS很多时候需要操作这些元素,首先我们要保证元素加载成功,才可以在JS中获取到(所以JS要放在结构之后加载,所以把JS放在<body>末尾)

如果把JS放在HTML标签前面了,如何等到结构加载完成再加载JS?
JS:window.onload=function() {} 页面中所有资源文件都加载完成执行操作
JQ:$(document).ready(function() {} ) 页面中的结构加载完成就会执行操作

3、 浏览器弹框

    <script>
        //JS中提供的浏览器弹框
        //1、alert:在浏览器中弹出一个提示框(提供确定按钮,点击确定弹框消失
        alert( {name: 'zzh'} ); //“ [object object]”
        alert( [12,23] ); //“ 12,23“
        alert( 1+1); //“2”
        //使用alert弹框提示信息,提示的内容最后都会被转换为字符串输出(调用了toString这个方法)
    <span class="hljs-comment">//2、confirm:在alert基础上增加了让用户选择性的操作(提供两个按钮:确定和取消)</span>
    <span class="hljs-comment">//当用户点击确定按钮的时候。我们接收到的结果是TRUE,点击的是取消按钮我们接收到的结果是FALSE,此后我们可以根据接收的结果做不同的处理即可。</span>

    <span class="hljs-comment">//3、prompt:在confirm基础上让用户输入的效果</span>
    <span class="hljs-comment">//当用户点击确定按钮的时候,我们将会获取到用户输入的内容,(如果用户没有输入任何内容,获取的结果是空字符串),点击的是取消按钮我们接收到的结果是null</span>
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>

4、控制台输出

控制台输出:方便开发人员进行调试的 (F12打开浏览器的控制台)
(1)console.log:在控制台输出,优势是不会转换数据类型,输出什么格式的数据都可以
(2)console.dir:比log输出的更详细一些
(3)console.table:把JSON数据展示成一个表格
(4)document.write:向页面中打印输出内容

二 JS中的变量/常量及数据类型

>ECMAScript(ES):规定了JS的一些基础核心的知识(变量、数据类型、语法规范、操作语句等)
>DOM:document object model 文档对象模型,里面提供了一些属性和方法,可以让我们操作页面中的元素
>BOM:browser object model 浏览器对象模型,里面提供了一些属性和方法,可以让我们操作浏览器

1、JS定义变量的方式

  • var 变量 = 值;(ES5) (ES6中定义变量使用let)
var num = 12;
var str = 'zzh';

2、JS定义常量的方式

  • const 常量 = 值;

3、JS中的命名规范

(1)JS中严格区分大小写

var test = ‘zzh’;
var Test = 'sxz';     //test和Test是两个不同的变量

(2)遵循国际命名规则-“驼峰命名法”
第一个单词首字母小写,其余每一个有意义的单词首字母大写

var studentInfo = 'zzh';

(3)命名的时候可以使用 $ _ 数字 字母 ,但是数字不能作为名字的第一位

var $xxx;  //一般都是应用JQ获取到的值
var _xxx;  //一般这样的情况代表变量是一个全局变量或者公用的变量

(4)JS中很多的词都是有特殊含义的,我们把这些词叫做关键字;现在没有特殊含义,以后可能会作为关键词的,我们叫做保留字,保留字和关键字都不可以随便用来命名

4、JS中的数据类型

  • (1)基本数据类型(值类型)
    number:数字
    string:字符串 //单双引号包裹起来的都是字符串,单双引号没有区别
    boolean:布尔 //只有两个值 true和false
    null:空对象指针
    undefined:未定义

  • (2)引用数据类型
    object对象数据类型 {name:'zzh',age:18} 、[12,23,34]
    function函数数据类型 function fn() { }
    object可分为 {}普通对象、[]数组、/^$/正则......
    对象数据类型的作用:把描述同一个事物(同一个对象)的属性和方法放在一个内存空间下,起到了分组的作用,这样不同的事物之间的属性即使属性名相同,相互也不会发生冲突。
    我们把这种分组编写代码的模式叫做“单例模式”。单例模式是一种项目开发中经常使用的模式,因为项目中我们可以使用单例模式来进行“模块化开发”。

检测数据类型的四种方法:
typeof:检测数据类型的运算符
instanceof:检测某个实例是否属于这个类
constructor:获取当前实例的构造器
Object.prototype.toString.call(最常用、最难):获取当前实例的所属类信息

(3)typeof:

  • 使用typeof检测,返回结果是一个字符串,字符串中包含的内容证明了值是属于什么类型的。
  • 局限性:
    1、typeof null不是‘null’而是‘object’,因为null虽然是单独的一个数据类型,但是他原本意思是空对象指针,浏览器使用typeof检测的时候会把他按照对象来检测。
    2、使用typeof无法具体细分出到底是数组还是正则,因为返回的结果都是‘object’。
    (4)布尔 Boolean():
  • 把其他数据类型的值转换为布尔类型
  • 只有0 、NaN 、 空字符串 、null 、undefined这五个数据值转换为布尔类型的false,其余的都会变为true。
    (5)叹号!:
    JS中的叹号还有一个作用:“取反”,先把值转换为布尔类型,然后再去取反。
    (6)两个叹号!!:
    在一个叹号取反的基础上再取反,取两次反相当于没有做操作,但是却已经把其他类型值转换为布尔类型了,和Boolean是相同的效果。
    (7)字符串:
    在JS中单引号和双引号包起来的都是字符串。
    常用方法:charAt charCodeAt、
    substr substring slice、
    toUpperCase toLowerCase、
    indexOf lastIndexOf、
    split、
    replace
    (8)Number()方法
    把其他数据类型值转换为number类型的值
Number('12') -> 12
Number('12px') -> NaN
在使用Number转换的时候只要字符串中出现任何一个非有效数字字符,最后的结果都是NaN 

Numbertrue) -> 1
Numberfalse) -> 0
Numbernull) -> 0
Numberundefined) -> NaN
Number([]) -> 0 把引用数据类型转换为number,首先需要把引用数据类型转换为字符串(用到toString方法),再把字符串转换为number即可
Number([]) => [ ] -> ’ ’ ’ ’ -> 0
Number([12]) => [12] -> ‘12’ ‘12’ -> 12
Number([12,23]) => [12,23] -> ‘12,23’ ‘12,23’ -> NaN 因为12,23中出现了一个非有效数字字符
Number({name:‘zzh’}) -> NaN
Number({}) -> NaN

(9)数字number:
JS中多增加了一个number类型的数据:NaN
NaN: not a number ,不是一个数,但是属于number类型
NaN == NaN :false ,NaN和任何其他值都不相等

isNaN() ;  用来检测当前这个值是否是非有效数字,如果不是有效数字检测的结果是true,反之是有效数字则为false

isNaN0) -> false
isNaN(NaN) -> true
isNaN(‘12’) ->false 当我们使用isNaN检测值的时候,检测的值不是number类型的,浏览器会默认的把值转换为number类型,然后再去检测
isNaN( [] ) -> false

(10)parseInt()
也是把其他数据类型值转换为number,和Number方法在处理字符串的时候有区别

Number('12px') -> NaN
parseInt('12px') -> 12
parseInt('12px13') -> 12
提取规则:从左到右依次查找有效数字字符,直到遇见非有效数字字符为止(不管后面是否还有数字,都不找了),把找到的转换为数字。
parseInt('px12') -> NaN

(11)parseFloat()
在parseInt的基础上可以识别小数点

parseInt('12.5px') -> 12
parseFloat('12.5px') -> 12.5

(12)null和undefined
空字符串和null的区别:
空字符串相对于null来说开辟了内存,消耗了一点点的性能,就像是种树,空字符串属于挖了个坑,但是没有种任何东西,null是连坑都没挖。
null和undefined的区别:
null一般都是暂时没有,预期中以后会有的(可能以后也没有达到预期),在JS中,null一般都是手动先赋值为null,后期我们在给其赋具体值。
undefined:完全没在预料之内的。
(13)对象数据类型object

var obj = {name:'zzh',age:18} ;
每一个对象都是有零到多组 属性名( key值):属性值(value值)组成的,或者说有多组键值对组成的,每一组键值对中间用逗号分隔,对象的属性名是字符串或者数字格式的,存储的属性值可以是任何的数据类型。
var obj = {name:'zzh',age:18} ;

获取某个属性名对应的属性值:
1、对象名.属性名 :忽略了属性名的单双引号
2、对象名[属性名] :不能忽略单双引号
obj.name 、obj['name']
如果属性名是数字:
obj.0语法不支持 obj[0] 或者 obj['0'] 两种都可以支持
如果操作的属性名在对象中不存在,获取的结果是undefined。
设置/修改:obj.sex = 'man' ; obj['age'] = 9;

  • 删除:
    1、假删除:让其属性值赋值为null,但是属性还在对象中 ,obj.sex = null ;
    2、真删除:把整个属性都在对象中暴力移除 delete obj.sex 。

三 基本数据类型和引用数据类型的区别

JS是运行在浏览器(内核、引擎)中的,浏览器会为JS提供赖以生存的环境(提供给JS代码执行的环境),称之为全局作用域。
基本数据类型:是按值操作的,基本数据类型在赋值的时候,是直接的把值赋给变量既可。
引用数据类型:是按照空间地址(引用地址)来操作的。

var n={name:'zzh'};
1、先创建一个变量n;
2、浏览器首先会开辟一个新的存储空间(内存空间),目的是把对象中需要存储的内容(键值对)分别的存储在这个空间中,为了方便后期找到这个空间,浏览器给空间设定一个地址(16进制)。
3、把空间的地址赋值给了变量

四 函数数据类型

函数是引用数据类型,所以函数数据类型也是按照引用地址来操作的。

function 函数名() {
   函数体:实现某一个功能的具体JS代码
}
  • 创建函数时,也会开辟一个新的内存空间,空间中存储的是函数体中的代码,但是此时的代码都是字符串里的字符而已。函数只创建不执行没有意义,因为空间中存储的都是毫无意义的字符串。
  • 函数执行时,浏览器会创建一个供函数中代码执行的私有环境,称之为私有作用域。

五 for in 循环

1、for in:用来遍历(循环)对象键值对的。
2、对象中有多少组键值对,for in循环就遍历多少次(不一定)。
3、每一次循环KEY这个变量存储的都是当前循环这组键值对的属性名。
4、KEY存储的值都是字符串格式的(不管属性名是否为数字)。
5、在for in循环遍历的时候,大部分浏览器都是先把对象中的键值对进行排序(把数字属性名的排在前面,并且排列的时候按照数字由小到大排列)(小数不算做数字,算作字母,),其次在把非数字的属性名按照之前编写的顺序排列,循环的时候按照重新排列的顺序依次遍历。

console.log(obj[key]); 
每一次循环把key变量存储的值(当前遍历的属性名)获取到放在中括号中,获取obj中对应属性的属性值
obj['key']  obj.key  : 都代表同一个意思,属性名是key
obj[key]  :属性名不是key,而是key变量存储的值

六 数据类型转换

把其他数据类型转换为number类型
1、isNaN、Number、parseInt、parseFloat
2、在进行加减乘除数学运算的时候

' ' -> 0   '12' -> 12   '12px'->12/NaN    null -> 0  undefined -> NaN
{}  /^$/  function() {}  -> NaN

引用数据类型转换为数字
通过toString方法把数组转换为字符串,然后在调用Number把字符串转换为数字

[]  ->  ' '  ->  0
[12] -> '12' -> 12
[12,23] -> '12,23' -> NaN

JS中的数学运算
加+ 减- 乘* 除/
1、除了加法有特殊性,其余的运算符都是数学运算,也就是遇到非数字类型,需要把其转换为number在进行运算。
2、加法的特殊性:在遇到字符串的时候,+不是数学运算,而是字符串拼接,只要不遇到字符串就是数学运算。
3、字符串拼接:是把其他的值转换为字符串然后再拼接。其他数据类型的toString是直接的把值用单双引号包起来即可,只有对象有特殊性,对象.toString() === ' [Object Object]'

1- '1' = 0
10 * null = 0 
10 / undefined = NaN
10 * [10] = 100
1 + ‘1’ = ‘11null + ‘1’ = ‘null1’

将其他类型转换为布尔类型
Boolean 、!、 !!
1、在条件判断的时候,也是转换为布尔类型,然后验证条件的真假。
2、只有0、NaN、空字符串、null、undefined五个转换为false,其余的都是转换为true。

if(box) {
}
首先是把box变量存储的值获取到,转换为布尔类型,如果为true条件成立,反之不成立。

在使用==进行比较的时候
在使用==进行比较的时候,如果左右两边数据类型不相同,浏览器会默认转换为相同的类型,然后在比较(===不会这样操作)。

1、对象和对象:比较的是空间地址,不是相同的空间,结果肯定是false
[] == [] -> false
var a = { } ;
var b = a ;
a == b ;  ->true
2、对象和数字:把对象转换为数字
[] ==  0 ; -> true 
{} == NaN ; -> false     // NaN和自己不相等和其他任何值都不相等
3、对象和字符串:把两边都转换为数字在进行比较
[] == ' ' ;    ->true 
4、对象和布尔:把两边都转换为数字在进行比较
[] == true  -> false
[] == false -> true
![] == false -> true   因为![]是把数组变为布尔在取反 所有false == false -> true

5、字符串和数字:字符串转换为数字
6、字符串和布尔:都转为数字
7、布尔和数字:布尔转换为数字
规律:两个等于号比较,左右两边数据值的类型不一样,浏览器会把两边的类型都转换为数字然后在比较。但是null和undefined除外。

null == undefined -> true 
null === undefined ->false 
null == 0 ->false 
null以及undefined和其他任何值都不相等

七 Math中常用的方法

数学函数:但是他是对象数据类型的。
Math对象中给我们提供了很多常用的操作数字的方法。
1、abs :
Math.abs :取绝对值
2、ceil && floor:
Math.ceil:向上取整
Math.floor:向下取整

Math.ceil(12.1) -> 13 
Math.ceil(-12.1) -> -12
Math.floor(12.9) -> 12 
Math.floor(-12.9) -> -13

3、round:
Math.round:四舍五入

Math.round(12.5) -> 13  正数中5包含在向上
Math.round(-12.5) -> -12   负数中5包含在向下
Math.round(-12.51) -> -13

4、random:
Math.random : 获取 (0,1)之间的随机小数
获取[0,10]之间的随机整数
Math.round(Math.random()10)
获取[3,15]之间的随机整数
Math.round(Math.random()
12+3)
获取[n,m]之间的随机整数
Math.round(Math.random()*(m-n)+n)
5、max && min:
Math.max:获取一组值中的最大值
Math.min:获取一组值中的最小值
6、PI :
Math.PI :获取圆周率π
7、pow && sqrt :
Math.pow : 获取一个值的多少次幂
Math.sqrt : 开平方

八 字符串中常用的方法

在JS中用单双引号包裹起来的都是字符串。
1、字符串就是由零到多个字符组成的。第一个字符索引为0,第二个字符索引为1...以数字作为索引,从零开始的。
2、有一个叫做length的属性,存储的是当前字符串中字符的个数(字符串的长度)。如果指定的索引不存在,则获取的结果是undefined。
字符串操作方法:

  • 1、charAt && charCodeAt
    str.charAt(索引):返回指定索引位置的字符,和str[索引]的区别在于,当指定的索引不存在的时候,中括号的方式获取的是undefined,而charAt获取的是空字符串。
    str.charCodeAt(索引):在charAt基础上,把获取的字符变为Unicode编码值(对于ASCII码表),48-57是0-9 , 65-90是A-Z , 97-122是a-z
    String,fromCharCode(十进制的Unicode值):把值按照ASCII码表中的信息,转化为原有的字符,和charCodeAt正好对应。
  • 2、substr && substring && slice
    实现字符串截取的三个方法:
    str.substr(n,m):从索引n开始,截取m个字符。
    str.substring(n,m):从索引n开始,截取到索引为m处(不包含m),把找到的部分截取。
    str.slice(n,m):和substring语法一样,区别在于slice支持以负数做索引。当索引为负数的时候,浏览器在处理的时候,是用字符串的总长度加上负数索引,然后按照正数处理操作。

1、如果只传递了n,(str.substr(n)/str.substring(n)),相当于从索引n开始一直截取到字符串的末尾。
2、如果传递的索引超出最大限制,也是把能截取的部分截取掉即可。
3、如果一个参数都不传递,相当于把整个字符串都截取(字符串的克隆)。

  • 3、toUpperCase && toLowerCase
    str.toUpperCase:把字母全部大写
    str.toLowerCase:把字母全部大写
  • 4、indexOf && lastIndexOf
    str.indexOf:获取当前字符在字符串中第一次出现位置的索引。
    str.lastIndexOf:获取的是最后一次出现位置的索引。

如果当前字符在字符串中没有出现过,结果是-1,我们根据这个规律可以验证一下当前字符串中是否包含某个字符。

  • 5、split
    str.split:按照某一个字符把字符串拆分成数组中的某一项,和数组中的join方法是对应的。
  • 6、replace
    str.replace:实现字符的替换。执行一次replace只能替换一次,如果有好几个都需要替换,在不使用正则的情况下我们需要执行很多次replace。有些需求即使执行很多次replace也实现不了,此时需要使用正则处理,真实项目中replace一般都是和正则搭配使用的。
  • trim && trimLeft && trimRight
    str.trimLeft:去除字符串开始的空格。
    str.trimRight:去除字符串结尾的空格。
    str.trim:去除字符串首尾的空格。

九 DOM基础

DOM:document object model文档对象模型,提供一些属性和方法可以让我们去操作DOM元素。
1、获取DOM元素的方法

  • document.getElementById 一个元素
  • [context].getElementsByTagName 元素集合
  • [context].getElementsByClassName 元素集合
  • document.getElementsByName 节点集合
  • document.documentElement 获取整个HTML对象
  • document.body 获取整个body对象
  • document.head 获取整个head对象
  • [context].querySelector 一个元素对象
  • [context].querySelectorAll 获取元素集合
    getElementById
    此方法的上下文只能是document。一个HTML页面中元素的ID理论上是不能重复的。
  • 1、如果页面中的ID重复了,我们获取的结果是第一个ID对应的元素对象。
  • 2、在IE7及更低版本的浏览器中,会把表单元素的name值当做 ID来识别使用(项目中尽量不要让表单的name和其他元素的ID相同)。
  • 3、如果我们把JS放在结构的下面,我们可以直接使用ID值来获取这个元素(不需要通过getElementById获取)而且这种方式会把页面中所有ID是它的元素都获取到(元素对象/元素集合)。 这种方式不推荐。
    getElementsByTagName
  • 1、上下文是可以自己来指定。
  • 2、获取到的结果是一个元素集合(类数组集合)。获取的结果是集合,哪怕集合中只有一项,我们想要操作这一项(元素对象),需要先从集合中获取出来,然后再操作。
  • 3、在指定的上下文中,获取所有子子孙孙元素中标签名叫做这个的(后代筛选)
    getElementsByClassName
  • 1、上下文也可以随意指定,获取的结果也是一个元素集合(类数组集合)
  • 2、真实项目中我们经常会通过样式类名来获取元素,但是getElementsByClassName 这个方法在IE6-8是不兼容的。
    getElementsByName
  • 1、通过元素的NAME属性值获取一组元素(类数组:节点结合NodeList)
  • 2、他的上下文也只能是document
  • 3、IE浏览器只能识别表单元素的name属性值,所以这个方法一般都是用来操作表单元素的。
    documentdocumentElement / documentbody
    获取HTML或者BODY(一个元素对象)
    querySelector / querySelectorAll
  • 1、在IE6-8不兼容,而且也没什么特别好的方法处理他的兼容,所以这两个方法一般多用于移动端开发使用。
    querySelector:获取一个元素对象
    querySelectorAll:获取一个元素组合

2、DOM节点
node:节点,浏览器认为在一个HTML页面中的所有内容都是节点(包括标签、注释、文字文本等)

  • 元素节点:HTML标签
  • 文本节点:文字内容(高版本浏览器会把空格和换行也当做文本节点)
  • 注释节点:注释内容
  • document文档节点
  • ......
    元素节点
    nodeType:1
    nodeName:大写标签名(在部分浏览器的怪异模式下,我们写的标签名是小写,他获取的就是小写)
    nodeValue:null
    [curEle].tagName:获取当前元素的标签名(获取的标签名一般都是大写)
    文本节点
    nodeType:3
    nodeName:#text
    nodeValue:文本内容
    注释节点
    nodeType:8
    nodeName:#comment
    nodeValue:注释内容
    文档节点
    nodeType:9
    nodeName:#document
    nodeValue:null
    3、DOM节点关系属性
    节点是用来描述页面中每一部分之间关系的,只要可以获取页面中的一个节点,那么就可以通过相关的属性和方法获取页面中所有的节点。
    childNodes
  • 1、获取当前元素所有的子节点(节点集合:类数组)。注:不仅仅是元素子节点,文本、注释等都会包含在内,子节点说明只是在儿子辈分中查找;
    children
  • 1、获取所有的元素子节点(元素集合)
  • 2、在IE6-8下获取的结果和标准浏览器中有区别(IE6-8中会把注释节点当做元素节点获取到)
    parentNode
  • 1、获取当前元素的父节点(元素对象)
    previousSibling / nextSibling
  • 1、previousSibling :获取当前节点的上一个哥哥节点(不一定是元素节点也可能是文本或者注释)
  • 2、nextSibling:获取当前节点的下一个弟弟节点
    previousElementSibling / nextElementSibling
  • 1、previousElementSibling :获取当前节点的上一个哥哥元素节点
  • 2、 nextElementSibling :获取当前节点的下一个弟弟元素节点
    IE6-8下不兼容
    firstChild / lastChild
  • 1、firstChild :当前元素所有子节点中的第一个(也不一定是元素节点,可能是文本和注释)
  • 2、lastChild :当前元素所有子节点中的最后一个

十 DOM的增删改

真实项目中,我们偶尔会在JS中动态创建一些HTML标签,然后把其增加到页面中。
documentcreateElement:在JS中动态创建一个HTML标签
appendChild

  • 1、容器.appendChild(新元素)
  • 2、把当前创建的新元素添加到容器的末尾位置
    inserBefore
  • 1、容器.inserBefore(新元素,老元素)
  • 2、在当前容器中,把新创建的元素增加到老元素之前
    真实项目中很多需求都是通过动态创建元素来完成的,其中有一个需求:解析一个URL地址每一部分的信息(包含问号传递的参数值)
  • 1、纯字符串拆分截取
  • 2、编写强大的正则,捕获到需要的结果
  • 3、通过动态创建一个a标签,利用a标签的一些内置属性来分别获取每一部分的内容
    QQ图片20180731172808.png

    QQ图片20180731173924.png

    removeChild
  • 1、容器.removeChild(元素)
  • 2、在当前容器中把某一个元素移除掉
    replaceChild
  • 1、容器.replaceChild(新元素,老元素)
  • 2、在当前容器中,拿新元素替换老元素
    cloneNode
  • 1、元素.cloneNode(false/true)
  • 2、把原有的元素克隆一份一模一样的,false:只克隆当前元素本身,true:深度克隆,把当前元素本身以及元素的所有后代都进行克隆
    set/get/removeAttribute
    给当前元素设置/获取/移除属性的(一般操作的都是他的自定义属性)
box.setAttribute('myIndex',0); 设置
box.getAttribute(myIndex);   获取
box.removeAttribute(myIndex);  移除

使用xxx.index=0和xxx.setAttribute('index',0)这两种设置自定义属性的区别?
xxx.index :是把当前操作的元素当做一个普通对象,为其设置一个属性名(和页面中的HTML标签没关系)
xxx.setAttribute:把元素当做特殊的元素对象来处理,设置的自定义属性是和页面结构中的DOM元素映射在一起的。

JS中获取的元素对象,可以理解为两种角色:

  • 与页面HTML结构无关的普通对象
  • 与页面HTML结构存在映射关系的元素对象
    元素对象中的内置属性,大部分都和页面的标签存在映射关系:
    1、xxx.style.backgroundColor = 'xxx'此时不仅把JS中对象对应的属性值改变了,而且也会映射到页面的HTML标签上(标签中有一个style行内样式、元素的样式改变了)
    2、xxx.className = 'xxx':此时不仅是把JS对象中的属性值改了,而且页面中的标签增加了class样式类(可以看见的)
    3、元素对象中的自定义属性xxx.index=0仅仅是把JS对象中增加了一个属性名(自定义的),和页面中的HTML没啥关系(在结构上看不见)
    4、xxx.setSttribute:通过这种方式设置的自定义属性和之前提到的内置属性差不多,都是和HTML结构存在映射关系的(设置的自定义属性可以呈现在结构上)

十一 Date日期操作

Date是日期类,通过它可以对时间进行处理。
获取当前客户端本机时间:获取的结果是一个日期格式的对象。

var time = new Date() ;
当前获取的时间不能作为重要的参考依据。
new Date();
->  Wed Aug 01 2018 09:21:53 GMT+0800 (中国标准时间)
typeof new Date();
->  "object"
  • time.getFullYear() 获取四位整数年
  • time.getMonth() 获取的月是0-11,代表1-12月
  • time.getDate() 获取日
  • time.getDay() 获取星期是0-6,代表周日-周六
  • time.getHours() 获取小时
  • time.getMinutes() 获取分钟
  • time.getSeconds() 获取秒
  • time.getMilliseconds() 获取毫秒
  • time.getTime() 获取当前日期距离‘1970-01-01 00:00:00’ 的毫秒差
var time = new Date('2017-10-21'); 
当new Date中传递一个时间格式的字符串,相当于把这个字符串转换为标准的时间对象格式(转换完成后,就可以调取上面的方法了)

十二 数组的基础结构

  • 数组是对象数据类型的。 typeof [] = 'object' 。
  • 数组也有属性名,只不过是数字,我们把数字属性名称之为他的索引:数组是以数字作为索引,索引从零开始,有一个length属性代表数组的长度。
  • 类数组:类似于数组,但是不是数组。
    (1)、通过getElementsByTagName获取的元素集合是类数组。
    (2)、函数中的实参集合arguments也是类数组。

十三 数组中的常用方法

可以通过console.dir(Array.prototype)看数组的常用方法。
实现数组的增加、修改、删除:

var ary = [12,23,34] ;

增加
1、push :向数组的末尾追加新内容。

  • 参数:一到多个,并且任何数据类型都可以追加。
  • 返回值:新增后数组的长度。
  • 原有数组改变了。
    2、unshift:向数组开头追加新内容。
  • 参数:需要追加的内容,可以是多个任何数据类型的值。
  • 返回值:新增后数组的长度。
  • 原有数组改变了。
    3、把数组当做一个普通的对象,使用对象键值对的操作,给其设置新的属性(索引)。
ary[ary.length] = xxx ; 
向数组的末尾追加了新内容

删除
1、pop:删除数组最后一项。

  • 参数:无
  • 返回值:被删除的那一项的内容。
  • 原有数组变了。
    2、shift:删除数组第一项。
  • 参数:无
  • 返回值:被删除的那一项的内容。
  • 原有数组变了。
  • 使用shift删除第一项之后,后面每一项的索引都要向前进一位,导致后面项的索引发生改变。
    3、delete:把数组当做普通对象操作。(不推荐使用)
delete ary[索引];
  • 当前项被删除后,原有数组的其他项的索引不会改变,当前数组的length也不会改变。
  • ary.length-- ; 删除数组最后一项。
    splice
    1、splice实现删除:
    splice(n,m) :从索引n开始删除m个(不写m是删除到数组的末尾,不写n和m,一项都不删除,返回的是一个新的空数组)
  • 返回值:被删除的内容(以一个新数组保存)。
  • 原有数组改变了。
    2、splice实现修改
    splice(n,m,x):在原有删除的基础上,用x代替删除的内容。
    3、splice实现增加
    splice(n,0,x):在修改的基础上,我们一项都不删除,把x插入到索引n的前面。
ary.splice(0,0,x)  向数组开头追加新的内容
ary.splice(ary.length,0,x)  向数组末尾追加新的内容

数组查询
1、slice:数组的查询。

  • 参数:slice(n,m)从索引n开始找到索引为m处(不包含m)。
  • 返回值:把找到的部分以一个新数组返回。
  • 原有数组不变。
  • slice(n):从索引n开始找到末尾
    slice(n)和slice() :数组克隆,克隆一份和原来数组一模一样的新数组。
  • slice支持负数索引,如果传递的索引为负数,浏览器解析的时候是按照 总长度+负数索引 来处理的。
    将两个数组进行拼接
    concat:将多个数组拼接在一起。
  • 参数:要拼接的内容(把内容放在原数组的后面),可以是一个数组,也可以是一些数据值。
  • 返回值:拼接后的新数组。
  • 原有数组没有改变。
    concat()什么都没有拼接,相当于把原有数组克隆了一份一模一样的新数组出来。
    把数组转换为字符串
    1、toString:实现把数组转换为字符串(转换后的字符串以逗号分隔每一项)。
  • 参数:无
  • 返回值:转换的字符串。
  • 原有数组不改变。
    2、join:把数组按照指定的分隔符转换为字符串,和字符串中的split相对应。
  • 参数:指定的连接符。
  • 返回值: 转换后的字符串。
  • 原有数组不改变。


    QQ图片20180801113451.png

已知数组中的每一项都是数字,想实现数组求和,如何实现?

1、循环实现
var total = null ;
for(var i=0;i<ary.length;i++) {
  total+=ary[i];
}
2、利用join
var total = eval(ary.join('+'))  
eval:把字符串变为JS表达式执行。

实现数组中每一项的排序和排列
1、reverse:把数组中的每一项倒过来排列。

  • 参数:无
  • 返回值:排序后的数组。
  • 原有数组改变。
    2、sort:实现数组的排序。
  • 参数:无或者回调函数
  • 返回值:排序后的数组
  • 原有数组改变。

1、不传递参数的情况下:可以给10以内的数字进行升序排列,但是超过10的就无法处理了(多位数只识别第一位)。
2、传递参数:ary.sort(function(a,b) { return a-b; 升序 return b-a; 降序 } );

验证数组中是否包含某一项
indexOf / lastIndexOf :获取当前项在数组中第一次或者最后一次出现位置的索引。

  • 数组中的这两个方法在IE6-8下不兼容
  • 字符串中的这两个方法兼容所有的浏览器
  • 如果当前数组中并没有这一项,返回的索引是-1,我们根据这一点可以验证数组中是否包含这一项。
    遍历数组中的每一项的方法
    以下方法在IE6-8中都不兼容:
  • 1、forEach:遍历数组中的每一项
ary.forEach(function(value,index)  {
    数组中有多少项,当前回调函数执行多少次,每一次传递进来的value就是当前遍历数组这一项的值,index就是遍历这一项的索引
} );
  • 2、map:遍历数组中的每一项,在forEach的基础上,可以修改每一项的值。
ary.map(function(value,index)  {
    数组中有多少项,当前回调函数执行多少次,每一次传递进来的value就是当前遍历数组这一项的值,index就是遍历这一项的索引。
   return xxx;  return后面返回的结果就是把当前遍历的这一项修改为xxx
} );
  • filter、find、reduce、every......
    数组去重
    1、双for循环遍历法:遍历数组中的每一项,拿每一项和他后面的项依次比较,如果相同了,则把相同的这一项在原来数组中删除即可。
    1.png

    2.png

    3.png

    2、利用indexOf来验证当前数组中是否包含某一项,包含把当前项删除掉。
    4.png

    3、对象去重法:遍历数组每一项,把每一项作为新对象的属性名和属性值存储起来。在每一次向对象中存储之前,首先看一下原有对象中是否包含了这个属性,用typeof obj[xxx] = 'undefined' 说明当前对象中没有xxx这个属性,如果已经存在这个属性说明数组中的当前项是重复的,所以在原有数组中删除这一项,不在向对象中存储这个结果,如果不存在,则把当前项作为对象的属性名和属性值存储进去即可。
    5.png

    6.png

    数组排序
    1、冒泡排序
  • 原理:让数组中的当前项和后一项进行比较,如果当前项大于后一项,我们让两者交换位置(小->大)。具体比较的论数:ary.length-1。
    7.png

    2、递归:函数自己调用自己
    3、快速排序
function quick(ary) {
    if (ary.length <= 1) {
        return ary;
    } 
    var centerIndex = Math.floor(ary.length/2),
        centerValue = ary.splice(centerIndex,1)[0];
    var aryLeft = [],
        aryRight = [];
    for (var i = 0; i < ary.length; i++) {
        var cur = ary[i];
        cur < centerValue ? aryLeft.push(cur) : aryRight.push(cur);
    }
    return quick(aryLeft).concat(centerValue,quick(aryRight));
}

4、插入排序


function insert(ary) {
    var handAry = [];
    handAry.push(ary[0]);
    for (var i = 1; i < ary.length; i++) {
        var item = ary[i];
        for (var j = handAry.length-1; j >= 0; j--) {
            if (item > handAry[j]) {
                handAry.splice(j+1, 0, item);
                break;
            }
            if (j===0) {
                handAry.unshift(item);
            }
        }
    }
    return handAry;
}

猜你喜欢

转载自blog.csdn.net/ganlubaba666/article/details/84035520